BZOJ 3749 [POI2015]Łasuchy

来源:互联网 发布:ubuntu lts 编辑:程序博客网 时间:2024/05/21 08:31

Description
圆桌上摆放着n份食物,围成一圈,第i份食物所含热量为c[i]。
相邻两份食物之间坐着一个人,共有n个人。每个人有两种选择,吃自己左边或者右边的食物。如果两个人选择了同一份食物,这两个人会平分这份食物,每人获得一半的热量。
假如某个人改变自己的选择后(其他n-1个人的选择不变),可以使自己获得比原先更多的热量,那么这个人会不满意。
请你给每个人指定应该吃哪一份食物,使得所有人都能够满意。


【题目分析】
动态规划好题。


【代码】

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int f[1000002][5];//1 给左边吃;2 给右边吃;3 两个一起吃;4 两个人都不吃 int a[1000002],n;int ans[1000002];bool dp(int s){    memset(f,0,sizeof f);    f[1][s]=1;    for (int i=2;i<=n;++i)    {        if (f[i-1][1]&&a[i-1]<=a[i]*2) f[i][1]=1;        if (f[i-1][4]&&a[i-1]<=a[i])   f[i][1]=4;        if (f[i-1][2]&&a[i]<=a[i-1]*2) f[i][2]=2;        if (f[i-1][3]&&a[i-1]>=a[i])   f[i][2]=3;        if (f[i-1][1]&&a[i-1]<=a[i])   f[i][3]=1;        if (f[i-1][4]&&a[i-1]*2<=a[i]) f[i][3]=4;        if (f[i-1][2]&&a[i-1]>=a[i])   f[i][4]=2;        if (f[i-1][3]&&a[i]*2<=a[i-1]) f[i][4]=3;    }    return f[n][s];}void print(int u){    for(int i=n;i>=1;i--){        if(u==1)ans[i-1]=(i-1)%(n-1)+1;        if(u==2)ans[i]=(i-1)%(n-1)+1;        if(u==3)ans[i-1]=ans[i]=(i-1)%(n-1)+1;        u=f[i][u];    }    for(int i=1;i<n;i++)printf("%d%c",ans[i],i==n-1?'\n':' ');}int main(){    scanf("%d",&n);    for (int i=1;i<=n;++i) scanf("%d",&a[i]);    a[++n]=a[1];    for (int i=1;i<=4;++i)        if (dp(i))        {            print(i);            return 0;        }    printf("NIE\n");    return 0;}
0 0
原创粉丝点击