每个食物有四种状态
①case=0:这个食物没人吃
②case=1:这个食物被左边人吃
③case=2:这个食物被右边人吃
④case=3:这个食物被两边人共享
那么就可以暴力枚举第一个食物的case然后递推就好了
pos[i][case]表示第i-1个食物的状态为pos[i][case]的情况下第i个食物的状态可以为case(也就是前驱)
注意是个环所以第pos[1][case]的前驱应该是第n个食物的状态
如果你枚举的当前第一个食物状态k合法(也就是说pos[1][k]存在前驱)就说明当前是个合法解
递推过程主要是通过当前两个食物的量来判定,程序里有
#include<stdio.h> #include<string.h> int a[1000005], ans[1000005], pos[1000005][4]; int main(void) { int n, i, k, now; while(scanf("%d", &n)!=EOF) { for(i=1;i<=n;i++) scanf("%d", &a[i]); a[n+1] = a[1]; for(k=0;k<=3;k++) { memset(pos, -1, sizeof(pos)); pos[1][k] = 233; for(i=2;i<=n+1;i++) { if(~pos[i-1][0]) { if(a[i]>=a[i-1]) pos[i][1] = 0; if(a[i]>=a[ i-1]*2) pos[i][3] = 0; } if(~pos[i-1][1]) { if(a[i]*2>=a[i-1]) pos[i][1] = 1; if(a[i]>=a[i-1]) pos[i][3] = 1; } if(~pos[i-1][3]) { if(a[i]*2<=a[i-1]) pos[i][0] = 3; if(a[i]<=a[i-1]) pos[i][2] = 3; } if(~pos[i-1][2]) { if(a[i]<=a[i-1]) pos[i][0] = 2; if(a[i]<=a[i-1]*2) pos[i][2] = 2; } } if(~pos[n+1][k]) { now = pos[n+1][k]; for(i=n;i>=1;i--) { if(now==1) ans[(i+n-2)%n+1] = i; if(now==2) ans[i] = i; if(now==3) ans[i] = i, ans[(i+n-2)%n+1] = i; now = pos[i][now]; } printf("%d", ans[1]); for(i=2;i<=n;i++) printf(" %d ", ans[i]); break; } } if(k==4) printf("NIE\n"); } return 0; }