• HDU 2191悼念512汶川大地震遇难同胞——珍惜如今,感恩生活(多重背包)


    HDU 2191悼念512汶川大地震遇难同胞——珍惜如今。感恩生活(多重背包)

    http://acm.hdu.edu.cn/showproblem.php?pid=2191

    题意:

           如果你有资金n元, 然后有m种大米, 每种大米价格为cost[i], 重量为val[i], 数量为num[i]. 如今问你用n元钱最多能买多重的大米?

    分析:

           本题是典型的多重背包问题.

           我们令dp[i][j]==x表示仅仅购买前i种大米, 且总费用<=j时能购买的大米最大重量为x.

           初始化: dp为全0.

           因为每种大米有数量num[i], 所以我们分以下两种情况做:

           cost[i]*num[i]>=n, 我们直接对该种大米做一次全然背包过程就可以.

           cost[i]*num[i]<n , 我们把num[i]个第i类大米看成以下k+1种物品:

           1个(i类物品)  2个 4个 2^(k-1)个 以及 num[i]-2^k+1个

           我们对上述k+1种新物品每一个都做一个01背包就可以覆盖我们可能对第i种物品做出的全部选择.

           终于所求: dp[m][n]的值.

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=4000+5;
    
    int n;//金额
    int m;//大米种类
    int cost[100+5];//价格
    int val[100+5]; //重量
    int num[100+5]; //数量
    int dp[maxn];
    
    //一次01背包
    void ZERO_ONE_PACK(int cost,int val)
    {
        for(int i=n;i>=cost;i--)
            dp[i] = max(dp[i], dp[i-cost]+val);
    }
    
    //一次全然背包
    void COMPLETE_PACK(int cost,int val)
    {
        for(int i=cost;i<=n;i++)
            dp[i] = max(dp[i], dp[i-cost]+val);
    }
    
    //一次多重背包
    void MULTIPLE_PACK(int cost,int val,int num)
    {
        if(cost*num>=n)
        {
            COMPLETE_PACK(cost,val);
            return;
        }
    
        int k=1;
        while(k<num)
        {
            ZERO_ONE_PACK(k*cost,k*val);
            num -=k;
            k*=2;
        }
        ZERO_ONE_PACK(num*cost,num*val);
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            //读取输入
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
                scanf("%d%d%d",&cost[i],&val[i],&num[i]);
    
            //初始化+递推
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=m;i++)
                MULTIPLE_PACK(cost[i],val[i],num[i]);
    
            //输出结果
            printf("%d
    ",dp[n]);
        }
        return 0;
    }
    

  • 相关阅读:
    批处理文件入门
    批处理入门学习地址
    react资料
    React 学习参考资料链接
    Spring boot + jdbc学习笔记
    iOS-升级Https证书报错
    Java-006-循环结构和控制语句详解(while, dowhile ,for ,switch)
    Java-005-运算符详解
    Java-004-变量类型和修饰符详解
    Java-001简介和基础语法[类方法、实例方法、public class 与 class 区别](第一个Java程序)
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7261492.html
Copyright © 2020-2023  润新知