zoukankan      html  css  js  c++  java
  • [atAGC022D]Shopping

    称0到$L$的方向为左,同时为了方便,可以假设$0<t_{i}le 2L$

    当我们确定是进入店中的方向,根据这个店的位置以及购物时间,不难确定出来时火车经过0或$L$的次数,由于$0<t_{i}le 2L$,因此总共至少有一次且分别不超过1次,即分以下三类讨论:

    1.经过0未经过$L$,在该位置上标记为1

    2.经过$L$未经过0,在该位置上标记为-1

    3.经过$L$且经过0,在该位置上标记为1、-1

    同时,对于坐在车上经过0或$L$,也可以看作0或$L$上有一个商店,即在0上记录1,$L$上记录-1

    (特别的,对于初始位于0不记录,对于最后到达0记录)

    最后,将0到$L$每一个位置上的序列连结起来,即构成一个由1、-1构成的序列

    考虑这个序列的意义,每一个1即表示该次火车到0时自己所处的位置,-1类似

    下面来考虑火车,对于每一趟,确定一对1和-1(即该次其到0和$L$时我的位置),并将这一对1和-1删去,不难发现要保证:

    1.删去的1(的位置)必须在该对的-1之前,删去的-1必须在上一对(若存在)删去的1之后

    (可以理解一下,否则我仍然在上一次的商店中)

    2.最后一次删去的1必须在位置0上或为空(即最后要返回0)

    同时,这一方案的所需时间为这个序列长度*L(每一个1或-1恰好对应$L$的路程),因此可以看作构造最短的1和-1的序列,使得其可以以上述方法删除:

    先考虑上述删除的真正限制,首先仅考虑每一次1在-1,即要求前缀和非负,同时由于成对匹配,即1和-1的数量相同,整体前缀和为0

    (可以以括号序列的方式理解,但注意,我们并不要求其1和-1要以括号序列的配对方式删除,即若将删去的一对括号看成一个区间,是可以有交的,那么就会有多种解)

    同时,这并不充分,我们还要求其在0上存在1,且除去空前缀和整体以外,前缀和严格大于0

    典型的例子是${1,-1,1,-1}$,由于第一个1要最后删除,那么一定先删除3和4上的1和-1,那么根据第二点删去的-1必须在上一对删去的1之后,是无法删除第2个位置的

    关于这个的证明,套用上面这个例子就可以了,对于前缀和为0的前缀,最左边的1必然要与这之前的-1匹配,由于这是最后一次匹配,那么上一次不在这个前缀中的匹配与下一次匹配就一定不合法了

    同时,当满足这两条必要条件后,其是充分的,构造方案:

    先将第一个1和最后一个-1在最后匹配,由于要求-1在上一次1之后,一定合法

    接下来,由于本来前缀和大于0,现在即非负,那么从小到大枚举左括号去匹配最近的右括号即可(从小到大是为了防止下一次的右括号在这一次之前)

    总结一下,根据$t_{i}$和$v_{i}$可以算出每一个节点的类型,即能否填写这三类中的一种(只要存在可能就可以,至于合法性后面会判),之后可以在0和$L$分别加上若干个1和-1(要求0上至少1个),使得其除去空前缀和整体以外,前缀和严格大于0,且整体和为0

    0和$L$上添加1和-1肯定要尽量少,具体来说就是0上1的个数是$-min(最小的非整体前缀和,0)+1$,$L$上-1的个数是添加上0的1后的整体的和

    如果暴力dp的时间复杂度是$o(n^{2})$的,无法通过

    简单贪心,可以发现如果能取1或-1一定不会填两个(最多会导致0和$L$一个上面多一个,这不劣),且对于自由的,必然是前缀选1,后缀选-1,枚举+前后缀和即可

    (代码大概是有问题的,懒得查了)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 300005
     4 vector<int>v;
     5 int n,L,ans,x[N],t[N],vis[N][2],sum[N][2],mn[N][2];
     6 long long tot;
     7 int main(){
     8     scanf("%d%d",&n,&L);
     9     for(int i=1;i<=n;i++)scanf("%d",&x[i]);
    10     for(int i=1;i<=n;i++)scanf("%d",&t[i]);
    11     for(int i=1;i<=n;i++){
    12         tot+=(t[i]-1)/(2*L);
    13         t[i]=(t[i]-1)%(2*L)+1;
    14         if (2*x[i]>=t[i])vis[i][0]=1;//可以填1 
    15         if (2*(L-x[i])>=t[i])vis[i][1]=1;//可以填-1 
    16         if ((!vis[i][0])&&(!vis[i][1]))tot++;
    17         else{
    18             if (!vis[i][0])v.push_back(1);//必须-1 
    19             if (!vis[i][1])v.push_back(0);//必须1 
    20             if ((vis[i][0])&&(vis[i][1]))v.push_back(2);//任意 
    21         }
    22     }
    23     tot=tot*2+v.size();
    24     for(int i=0;i<v.size();i++){
    25         int p=1;
    26         if (v[i]==1)p=-1;
    27         sum[i+1][0]=sum[i][0]+p;
    28         mn[i+1][0]=min(mn[i][0],sum[i][0]);
    29     }
    30     for(int i=v.size()-1;i>=0;i--){
    31         int p=1;
    32         if (v[i])p=-1;
    33         if (i==v.size()-1)mn[i][1]=0;//强制不为全体的最小前缀和 
    34         else mn[i][1]=min(mn[i+1][1]+p,0);
    35         sum[i][1]=sum[i+1][1]+p;
    36     }
    37     //[0,i),[i,n)
    38     ans=0x3f3f3f3f;
    39     for(int i=0;i<=v.size();i++){
    40         int s0=1-min(mn[i][0],sum[i][0]+mn[i][1]);
    41         int s=sum[i][0]+sum[i][1]+s0;
    42         ans=min(ans,s0+s);
    43     }
    44     printf("%lld",(ans+tot)*L);
    45 }
    View Code
  • 相关阅读:
    Software Solutions CACHE COHERENCE AND THE MESI PROTOCOL
    CACHE COHERENCE AND THE MESI PROTOCOL
    Multiprocessor Operating System Design Considerations SYMMETRIC MULTIPROCESSORS
    Organization SYMMETRIC MULTIPROCESSORS
    PARALLEL PROCESSING
    1分钟内发送差评邮件
    Secure Digital
    SYMMETRIC MULTIPROCESSORS
    A Taxonomy of Parallel Processor Architectures
    parallelism
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14378126.html
Copyright © 2011-2022 走看看