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
  • 相关阅读:
    centos安装时各个版本的含义
    centos或者ubuntu设置ssh免密码登陆
    centos配置网卡
    如何卸载centos中自带的Java
    基于VHDL的8255可编程并行接口电路设计
    Norns.Urd 中的一些设计
    手把手教你写DI_3_小白徒手支持 `Singleton` 和 `Scoped` 生命周期
    手把手教你写DI_2_小白徒手撸构造函数注入
    手把手教你写DI_1_DI框架有什么?
    手把手教你写DI_0_DI是什么?
  • 原文地址:https://www.cnblogs.com/coclhy/p/11633401.html
Copyright © 2011-2022 走看看