• [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper (状态压缩DP)


    不打算把题目放着,给个空间传送门,读者们自己去看,传送门(点我)    

    这题是自己做的第一道状态压缩的动态规划。

    思路:

    在这题中,我们设f[i]为i在二进制下表示的那些牛所用的最小电梯数。

    设g[i]为i在二进制下表示的那些牛使用的电梯中剩下的最大容量。

    所以很明显的,我们只要枚举每一只牛就可以了。

    如果当前状态下,最大容量能装进某只牛,则装进去,并且用两个变量保存装进去后的f值与g值,否则再使用一个新的电梯,并且用变量保存用新电梯后的f与g值。

    在每次的枚举,我们还要将当前保存的f值与g值与原来保存的状态值进行对比,取最小的,在这,如果当前枚举的f值与原来保存的f值相等,则我们更新g值,在两者间取最大的即可。

    其中 i & (1 << j-1) 是判断第j只牛是否在状态i中,i | (1 << j-1) 表示将第j只牛装进去后的状态。

    下面贴出代码,有问题下面留言

    #include<cstdio>
    #include<algorithm>
    #define N 1<<20
    using namespace std;
    
    int f[N],g[N],w[20];
    
    int main(){
        int n,c;
        scanf("%d%d",&n,&c);
        for(int i = 1; i <= n; i++)scanf("%d",&w[i]);
        int mxx = (1 << n)-1;                //mxx为最终状态
        for(int i = 0; i <= mxx; i++)f[i] = 19999999,g[i] = c;
        f[0] = 0;
        for(int i = 0; i < mxx; i++){
            for(int j = 1; j <= n; j++)      //枚举每只牛
               if(!(i&(1 << j-1))){        //判断第j只牛是否在状态i中,不存在则进行计算
                       int nowf,nowg;      //当前f,g值
                      if(g[i] >= w[j]){      //如果原始最大剩余空间大于w[j]则说明可以将第j只牛装进去
                              nowg = g[i]-w[j];
                              nowf = f[i];
                      }
                      else nowg = c-w[j],nowf = f[i]+1;    //否则新用一个电梯
                      if(nowf < f[i | (1 << j-1)]){      //取原值与现值中的最小值
                              f[i | (1 << j-1)] = nowf;
                              g[i | (1 << j-1)] = nowg;
                      }
                      else if(nowf == f[i | (1 << j-1)])g[i | (1 << j-1)] = max(nowg,g[i | (1 << j-1)]);  //当nowf 与 f[i | (1 << j-1)]相等时,要更新g值最大,取更大那个
               }
        }
        if(g[mxx] < c)f[mxx]++;        //如果当前算得的最终状态剩下的容量小于c,则说明还需一个电梯
        printf("%d
    ",f[mxx]);
        return 0;
    }
  • 相关阅读:
    QuickPart
    C#在Word文档指定位置增加内容
    不同linux操作系统的内存管理及安全性
    团队作业(五):冲刺总结7
    团队作业(五):冲刺总结1
    信息安全系统设计与实现:第十四章学习笔记
    电子公文传输系统个人贡献
    OpenEuler 中C与汇编的混合编程
    团队作业(五):冲刺总结2
    OpenEuler 中C语言中的函数调用测试
  • 原文地址:https://www.cnblogs.com/bingdada/p/7695722.html
Copyright © 2020-2023  润新知