【题解】Luogu P3584 LAS dp
一个状态超多的dp
考虑对食物转移,设f[][0/1/2/3]表示不被选/被左吃/被右吃/被两边吃
只要考虑全每一种状态即可
dp
void dp(int x,int y){ if(~f[x][2]&&a[x]>=a[y])f[y][0]=2; else if(~f[x][3]&&a[x]>=a[y]*2)f[y][0]=3; if(~f[x][0]&&a[x]<=a[y])f[y][1]=0; else if(~f[x][1]&&a[x]<=a[y]*2)f[y][1]=1; if(~f[x][2]&&a[x]*2>=a[y])f[y][2]=2; else if(~f[x][3]&&a[x]>=a[y])f[y][2]=3; if(~f[x][0]&&a[x]*2<=a[y])f[y][3]=0; else if(~f[x][1]&&a[x]<=a[y])f[y][3]=1; }
code
1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace gengyf{ 4 #define ll long long 5 const int mod=1e5+3; 6 const int maxn=1e6+10; 7 inline int read(){ 8 int x=0,f=1; 9 char c=getchar(); 10 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 11 while(c>='0'&&c<='9'){x=(x*10)+c-'0';c=getchar();} 12 return x*f; 13 } 14 int f[maxn][4],n,a[maxn],ans[maxn],fl; 15 void dp(int x,int y){ 16 if(~f[x][2]&&a[x]>=a[y])f[y][0]=2; 17 else if(~f[x][3]&&a[x]>=a[y]*2)f[y][0]=3; 18 if(~f[x][0]&&a[x]<=a[y])f[y][1]=0; 19 else if(~f[x][1]&&a[x]<=a[y]*2)f[y][1]=1; 20 if(~f[x][2]&&a[x]*2>=a[y])f[y][2]=2; 21 else if(~f[x][3]&&a[x]>=a[y])f[y][2]=3; 22 if(~f[x][0]&&a[x]*2<=a[y])f[y][3]=0; 23 else if(~f[x][1]&&a[x]<=a[y])f[y][3]=1; 24 } 25 int main(){ 26 n=read(); 27 for(int i=1;i<=n;i++){ 28 a[i]=read(); 29 } 30 for(int s=0;s<4;s++){ 31 memset(f,-1,sizeof(f)); 32 f[1][s]=4; 33 for(int i=2;i<=n;i++)dp(i-1,i); 34 dp(n,1); 35 if(f[1][s]<4){ 36 int k=f[1][s]; 37 for(int i=n;i;i--){ 38 if(k==1||k==3)ans[(i-2+n)%n+1]=i; 39 if(k==2||k==3)ans[i]=i; 40 k=f[i][k]; 41 } 42 for(int i=1;i<=n;i++){ 43 printf("%d ",ans[i]); 44 } 45 fl=1;break; 46 } 47 } 48 if(!fl)puts("NIE"); 49 return 0; 50 } 51 } 52 signed main(){ 53 gengyf::main(); 54 return 0; 55 }