zoukankan      html  css  js  c++  java
  • luogu_P3584 [POI2015]LAS

    传送门:https://www.luogu.org/problem/P3584

    据说对人设状态会很复杂,所以就针对食物来设置状态

    f[i][0/1/2/3]分别表示不被吃/被左吃/被右吃/被都吃

    接下来看转移方程(依据是,在什么情况下前面那个人会做出当前选择,而不选别的选择显然是当前最优,更改后不会更优啊

    1. 不被吃,那前一个人为什么不吃c[i]?如果c[i-1]是一个人吃那么状态就是由f[i-1][2]转移而来(c[i-1]>c[i]),如果两个人吃由f[i-1][3]转移而来(c[i-1]/2>c[i])
    2. 被左边吃,前一个人为什么选择c[i]?如果c[i-1]被左边人吃则状态由f[i-1][1]转移而来(c[i-1]/2<c[i]),如果不被吃由f[i-1][0]转移而来(c[i-1]<c[i])
    3. 被右边吃,前一个人为什么不吃它?如果c[i-1]被右边人吃则状态由f[i-1][2]转移而来(c[i-1]>c[i]/2),如果被两个人吃由f[i-1][3]转移而来(c[i-1]/2>c[i]/2)
    4. 被都吃,那前一个人为什么选择分享而不吃左边?如果c[i-1]被左边吃则状态由f[i-1][1]转移而来(c[i-1]/2<c[i]/2),如果不被吃由f[i-1][0]转移而来(c[i-1]<c[i]/2

    最后因为是环,所以我们先枚举第一个食物的状态,然后看最后这个状态是否是最优状态(即是否合法)

    //代码巨丑...
    #include<cstdio>
    #include<cstring>
    #define R register
    typedef long long ll;
    using namespace std;
    int n,c[1001000];
    int f[1001000][4],ans[1001000];// 0_none  1_left  2_right  3_both
    int main () {
        scanf("%d",&n);
        for(R int i=1;i<=n;i++) scanf("%d",&c[i]);
        c[0]=c[n];c[n+1]=c[1];
        for(R int i=0;i<=4;i++){
            memset(f,-1,sizeof(f));
            f[1][i]=i;
            for(R int j=2;j<=n+1;j++){
                if(f[j-1][3]!=-1&&c[j-1]>=c[j]<<1)  f[j][0]=3;
                if(f[j-1][2]!=-1&&c[j-1]>=c[j])        f[j][0]=2;
                if(f[j-1][1]!=-1&&c[j]<<1>=c[j-1])     f[j][1]=1;
                if(f[j-1][0]!=-1&&c[j]>=c[j-1])        f[j][1]=0;
                if(f[j-1][2]!=-1&&c[j]<=c[j-1]<<1)  f[j][2]=2;
                if(f[j-1][3]!=-1&&c[j]<=c[j-1])        f[j][2]=3;
                if(f[j-1][0]!=-1&&c[j]>=c[j-1]<<1)    f[j][3]=0;
                if(f[j-1][1]!=-1&&c[j]>=c[j-1])      f[j][3]=1;
            }
            if(f[n+1][i]!=-1){
                int k=i;
                for(R int j=n;j>=1;j--){
                    if(k==1) ans[j]=j%n+1;
                    else if(k==2) ans[j%n+1]=j%n+1;
                    else if(k==3) ans[j]=ans[j%n+1]=j%n+1;
                    k=f[j+1][k];
                }
                for(R int j=1;j<=n;j++) printf("%d ",ans[j]);
                return 0;
            }
        }
        printf("NIE");
        return 0;
    }
    View Code
  • 相关阅读:
    67. Add Binary
    66. Plus One
    64. Minimum Path Sum
    63. Unique Paths II
    How to skip all the wizard pages and go directly to the installation process?
    Inno Setup打包之先卸载再安装
    How to change the header background color of a QTableView
    Openstack object list 一次最多有一万个 object
    Openstack 的 Log 在 /var/log/syslog 里 【Ubuntu】
    Git 分支
  • 原文地址:https://www.cnblogs.com/coclhy/p/11633401.html
Copyright © 2011-2022 走看看