• [gym102900H]Rice Arrangement


    (可以先阅读题目中关于顺逆时针的定义,避免理解错误)

    考虑一盘菜$b_{i}$被$a_{j}$吃掉,对于其最后一次移动:如果是顺时针,则称$b_{i}$的移动区间为$[a_{j},b_{i}]$(若$b_{i}<a_{j}$则为$[a_{j},n)cup[0,b_{i}]$的环),反之类似(特别的,如果$a_{j}=b_{i}$则区间为$[b_{i},b_{i}]$)

    记顺时针的最大移动区间为$l_{1}$,逆时针为$l_{2}$,答案即为$l_{1}+l_{2}+min(l_{1},l_{2})$

    若某两个人移动区间相互包含,对两者移动方向分类讨论,可以发现都可以更换配对方式使得$l_{1}$和$l_{2}$不增加,换言之存在最优解使得任意两盘菜移动区间不包含

    (注意:环的包含可以看作集合的包含)

    通过这个,我们可以得到这样一个结论:将$a_{i}$和$b_{i}$从小到大排序后,存在一组最优解,满足存在$x$使得是$a_{i}$匹配$b_{(i-1+x)mod k+1}$(其中$0le x<k$)

    (这个结论大概是挺难证的)

    有了这个结论,首先枚举$x$,即确定了配对方案

    接下来,先考虑暴力枚举$l_{1}$,之后将顺时针结果不超过$l_{1}$用顺时针做,再维护逆时针的最大值,通过将顺时针从小到大排序以及维护后缀逆时针最大值就可以做了

    时间复杂度为$o(k^{2}log k)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 1005
     4 pair<int,int>v[N];
     5 int t,n,m,ans,a[N],b[N],mx[N];
     6 int len(int x,int y){
     7     if (x<=y)return y-x;
     8     return m-(x-y);
     9 }
    10 int main(){
    11     scanf("%d",&t);
    12     while (t--){
    13         scanf("%d%d",&m,&n);
    14         for(int i=0;i<n;i++)scanf("%d",&a[i]);
    15         sort(a,a+n);
    16         for(int i=0;i<n;i++)scanf("%d",&b[i]);
    17         sort(b,b+n);
    18         ans=m;
    19         for(int i=0;i<n;i++){
    20             for(int j=0;j<n;j++)v[j]=make_pair(len(a[j],b[(j+i)%n]),len(b[(j+i)%n],a[j]));
    21             sort(v,v+n);
    22             mx[n]=0;
    23             for(int j=n-1;j>=0;j--)mx[j]=max(mx[j+1],v[j].second);
    24             ans=min(ans,mx[0]);
    25             for(int j=0;j<n;j++)ans=min(ans,v[j].first+mx[j+1]+min(v[j].first,mx[j+1]));
    26         }
    27         printf("%d
    ",ans);
    28     }
    29 }
    View Code
  • 相关阅读:
    【转】嵌入式软件:C语言编码规范
    【转】如何建立编码规范?
    RAS使用拨号网络拨号的类
    UDP 通讯代码
    【转】heap与stack的区别
    关于textarea在safari chrome下可拖动大小的问题
    Java网络编程入门
    诺基亚发布了它的第一台android手机,x和x+机型
    Spring学习笔记之入门(二)
    Spring学习笔记之入门(一)
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14360331.html
Copyright © 2020-2023  润新知