zoukankan      html  css  js  c++  java
  • 【HDU】2191 多重背包问题

    原题目:悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

    【算法】多重背包(有限背包) 动态规划

    【题解】http://blog.csdn.net/acdreamers/article/details/8563283

    优化:若物品数量(num[i])*物品重量(w[i])>背包容量(m),就相当于无限背包。

    对于num[i],可以拆成若干个01背包来实现1...num[i]的全覆盖,二进制原理:

    1...k中的数可以由1.2.4...2t.k-2t+1+1(2t+2 > k ≥ 2t+1)组成。

    具体实现见代码。

    还有一种优先队列优化的有限背包算法,不介绍。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=1010;
    int num[maxn],f[maxn],w[maxn],v[maxn],m,n;
    void zeroone_pack(int W,int V)
    {
        for(int i=m;i>=W;i--)f[i]=max(f[i],f[i-W]+V);
    }
    void complete_pack(int W,int V)
    {
        for(int i=W;i<=m;i++)f[i]=max(f[i],f[i-W]+V);
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
         {
             scanf("%d%d",&m,&n);
             memset(f,0,sizeof(f));
             for(int i=1;i<=n;i++)
              scanf("%d%d%d",&w[i],&v[i],&num[i]);//w[i]重量 value[i]价值
             for(int i=1;i<=n;i++)
             if(num[i]*w[i]>m)complete_pack(w[i],v[i]);
              else
               {
                   int k=1;
                   while(k<num[i])
                    {
                        zeroone_pack(w[i]*k,v[i]*k);
                        num[i]-=k;
                        k<<=1;
                    }
                   zeroone_pack(w[i]*num[i],v[i]*num[i]);
               }
             printf("%d
    ",f[m]);
         }
        return 0;
    }
    View Code
  • 相关阅读:
    冲刺NO.2
    冲刺NO.1
    用户场景描述
    【洛谷T2695 桶哥的问题——吃桶】
    【洛谷P4445 【AHOI2018初中组】报名签到】
    清北学堂2019.5.4
    清北学堂2019.5.3
    清北学堂2019.5.2
    清北学堂培训2019.5.1
    清北学堂培训2019.4.30
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6402790.html
Copyright © 2011-2022 走看看