• BZOJ3749 : [POI2015]Łasuchy


    设f[i][S]表示第i份食物被两个人吃的状态为S是否有可能,枚举f[1][]的情况后检验

    f[i][0]=(f[i-1][1]&a[i-1]>=a[i])|(f[i-1][3]&a[i-1]>=2*a[i])

    f[i][1]=(f[i-1][1]&2*a[i-1]>=a[i])|(f[i-1][3]&a[i-1]>=a[i])

    f[i][2]=(f[i-1][0]&a[i]>=a[i-1])|(f[i-1][2]&2*a[i]>=a[i-1])

    f[i][3]=(f[i-1][0]&a[i]>=2*a[i-1])|(f[i-1][2]&a[i]>=a[i-1])

    #include<cstdio>
    #define N 1000010
    int n,i,j,S,a[N],g[N][4],ans[N],c[N];
    bool f[N][4];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    bool dp(int S){
      for(i=1;i<=n;i++)for(j=0;j<4;j++)f[i][j]=0;
      f[1][S]=1;
      for(i=2;i<=n;i++){
        if(f[i-1][1]&a[i-1]>=a[i])f[i][0]=1,g[i][0]=1;
        else if(f[i-1][3]&a[i-1]>=2*a[i])f[i][0]=1,g[i][0]=3;
        if(f[i-1][1]&2*a[i-1]>=a[i])f[i][1]=1,g[i][1]=1;
        else if(f[i-1][3]&a[i-1]>=a[i])f[i][1]=1,g[i][1]=3;
        if(f[i-1][0]&a[i]>=a[i-1])f[i][2]=1,g[i][2]=0;
        else if(f[i-1][2]&2*a[i]>=a[i-1])f[i][2]=1,g[i][2]=2;
        if(f[i-1][0]&a[i]>=2*a[i-1])f[i][3]=1,g[i][3]=0;
        else if(f[i-1][2]&a[i]>=a[i-1])f[i][3]=1,g[i][3]=2;
      }
      for(j=0;j<4;j++)f[0][j]=f[n][j],f[1][j]=0;
      i=1;
      if(f[i-1][1]&a[i-1]>=a[i])f[i][0]=1,g[i][0]=1;
      else if(f[i-1][3]&a[i-1]>=2*a[i])f[i][0]=1,g[i][0]=3;
      if(f[i-1][1]&2*a[i-1]>=a[i])f[i][1]=1,g[i][1]=1;
      else if(f[i-1][3]&a[i-1]>=a[i])f[i][1]=1,g[i][1]=3;
      if(f[i-1][0]&a[i]>=a[i-1])f[i][2]=1,g[i][2]=0;
      else if(f[i-1][2]&2*a[i]>=a[i-1])f[i][2]=1,g[i][2]=2;
      if(f[i-1][0]&a[i]>=2*a[i-1])f[i][3]=1,g[i][3]=0;
      else if(f[i-1][2]&a[i]>=a[i-1])f[i][3]=1,g[i][3]=2;
      return f[1][S];
    }
    int main(){
      read(n);
      for(i=1;i<=n;i++)read(a[i]);a[0]=a[n];
      for(S=0;S<4;S++)if(dp(S))break;
      if(S==4)puts("NIE");
      else{
        ans[1]=S;
        for(i=n,j=g[1][S];i>1;j=g[i--][j])ans[i]=j;
        if(ans[1]==1||ans[1]==3)c[1]=1;
        if(ans[1]==2||ans[1]==3)c[n]=1;
        for(i=2;i<=n;i++){
          if(ans[i]==1||ans[i]==3)c[i]=i;
          if(ans[i]==2||ans[i]==3)c[i-1]=i;
        }
        for(i=1;i<=n;i++)printf("%d ",c[i]);
      }
      return 0;
    }
    

      

  • 相关阅读:
    测试72.思维好题
    pbds:STL平衡树
    测试69。这场因为轻视少了很多分。
    C++ 中的四种类型转换
    C++ 中的static关键字
    codeforces 1269 E K Integers
    P4556 [Vani有约会]雨天的尾巴 (线段树合并)
    P3521 [POI2011]ROT-Tree Rotations (线段树合并)
    codeforces 600E E. Lomsat gelral (线段树合并)
    线段树合并的一些题
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403202.html
Copyright © 2020-2023  润新知