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; }