[POI2015]LAS
动态规划:
这里用一种我想不到的思想,我们以美食来转移,设计状态$f[i][S](S\in\{0\sim3\})$其中$S$为$0$时表示第$i$个食物没有被人选,$1$表示被左边的人选了,$2$表示被右边的人选了,$3$表示被两个人同时选中
状态转移有点多,但是挺简单,不多赘述
接下来是美滋滋的代码时间~~~
#include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<algorithm> #define reg register using namespace std; const int N=1e6+5; int n,a[N],ans[N],f[N][4];//0:á?±???2??? 1:×ó±? 2:óò±? 3:á?±????? inline int read() { int x=0,w=1; char c=getchar(); while (!isdigit(c)&&c!='-') c=getchar(); if (c=='-') c=getchar(),w=-1; while (isdigit(c)) { x=(x<<1)+(x<<3)+c-'0'; c=getchar(); } return x*w; } inline bool work(int k) { memset(f,-1,sizeof(f)); f[1][k]=-2; for (reg int i=2;i<=n;i++) { if (~f[i-1][2]&&a[i-1]>=a[i]) f[i][0]=2; if (~f[i-1][3]&&a[i-1]>=a[i]*2) f[i][0]=3; if (~f[i-1][0]&&a[i]>=a[i-1]) f[i][1]=0; if (~f[i-1][1]&&a[i]*2>=a[i-1]) f[i][1]=1; if (~f[i-1][2]&&a[i-1]*2>=a[i]) f[i][2]=2; if (~f[i-1][3]&&a[i-1]*2>=a[i]) f[i][2]=3; if (~f[i-1][0]&&a[i]>=a[i-1]*2) f[i][3]=0; if (~f[i-1][1]&&a[i]>=a[i-1]) f[i][3]=1; } return ~f[n][k]; } inline void print(int k) { --n; for (reg int i=n;~i;i--) { if (k==1) ans[i]=i%n+1; if (k==2) ans[i+1]=i%n+1; if (k==3) ans[i]=ans[i+1]=i%n+1; k=f[i+1][k]; } for (reg int i=1;i<=n;i++) printf("%d ",ans[i]); exit(0); } int main() { n=read(); for (reg int i=1;i<=n;a[i++]=read()); a[++n]=a[1]; for (reg int i=0;i<4;i++) if (work(i)) print(i); puts("NIE"); return 0; }