p3584 [POI2015]LAS
作者:互联网
分析
f[i][S](S∈[0,4])表示第iii个食物没有被选/左边选/右边选/同时选的状态是由哪一个状态转移来的
我们需要满足两个条件:
每个人只能选择一个
改变选择之后不会比当前获得热量多
讨论$a_i$和$a_{i-1}$的大小关系进行转移
输出方案的时候由后向前推过去就好
先固定第一个的状态进行dp
枚举第一个的不同情况就可以了
代码
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<queue> #include<ctime> #include<vector> #include<set> #include<map> #include<stack> using namespace std; int c[1000100],dp[4][1000100],ans[1000100]; inline void go(int pre,int now){ if(~dp[2][pre]&&c[pre]>=c[now])dp[0][now]=2; else if(~dp[3][pre]&&c[pre]>=c[now]*2)dp[0][now]=3; if(~dp[0][pre]&&c[pre]<=c[now])dp[1][now]=0; else if(~dp[1][pre]&&c[pre]<=c[now]*2)dp[1][now]=1; if(~dp[2][pre]&&c[pre]*2>=c[now])dp[2][now]=2; else if(~dp[3][pre]&&c[pre]>=c[now])dp[2][now]=3; if(~dp[0][pre]&&c[pre]*2<=c[now])dp[3][now]=0; else if(~dp[1][pre]&&c[pre]<=c[now])dp[3][now]=1; } int main(){ int n,m,i,j,k; scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d",&c[i]); for(k=0;k<4;k++){ memset(dp,-1,sizeof(dp)); dp[k][1]=4; for(i=1;i<n;i++)go(i,i+1); go(n,1); if(dp[k][1]!=4){ int now=dp[k][1]; for(i=n;i>0;i--){ if(now==1||now==3)ans[(i-2+n)%n+1]=i; if(now==2||now==3)ans[i]=i; now=dp[now][i]; } for(i=1;i<n;i++)printf("%d ",ans[i]); printf("%d\n",ans[i]); return 0; } } puts("NIE"); return 0; }
标签:pre,now,int,POI2015,p3584,&&,include,dp,LAS 来源: https://www.cnblogs.com/yzxverygood/p/10357459.html