zoukankan      html  css  js  c++  java
  • HDU 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

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

    题目是多重背包的题目,但是我们可以写成是0/1背包的格式。

    0/1背包的代码:

    View Code
     1 #include <iostream>
     2 #define maxn 101
     3 using namespace std;
     4 int ans[maxn], v[maxn], w[maxn], num[maxn];
     5 int main()
     6 {
     7     int i, j, l, n, m, t;
     8     cin >> t;
     9     while(t--)
    10     {
    11         cin >> m >> n;
    12         for(i = 0; i < n; i++)
    13           cin >> v[i] >> w[i] >> num[i];
    14         for(i = 0; i <= m; i++)
    15           ans[i] = 0;
    16         for(i = 0; i < n; i++)
    17          for(j = 0; j < num[i]; j++)
    18           for(l = m; l >= v[i]; l--)
    19           if(ans[l-v[i]]+w[i] > ans[l])
    20             ans[l] = ans[l-v[i]]+w[i];
    21         cout << ans[m] << endl;       
    22     }
    23     return 0;
    24 }

    完全背包的代码:

    View Code
     1 #include <iostream>
     2 #define maxn 1001
     3 using namespace std;
     4 struct things
     5 {
     6     int cost, weight, amount;
     7 };
     8 things th[maxn];
     9 int ans[maxn], n, m;
    10 void zero_one_pack(int cost, int weight)
    11 {
    12     int j;
    13     for(j = m; j >= cost; j--)
    14     if(ans[j] < ans[j-cost]+weight)
    15      ans[j] = ans[j-cost]+weight;
    16 }
    17 void complete_pack(int cost, int weight)
    18 {
    19     int i, j;
    20     for(j = 0; j <= m; j++)
    21     if(j >= cost &&ans[j] < ans[j-cost]+weight)
    22      ans[j] = ans[j-cost]+weight;
    23 }
    24 void mulity_pack(things now)
    25 {
    26     int i;
    27     if(now.cost * now.amount >= m)
    28     {
    29         complete_pack(now.cost,now.weight);
    30     }
    31     else
    32     {
    33         for(i = 1; i < now.amount;)
    34         {
    35             zero_one_pack(i*now.cost, i*now.weight);
    36             now.amount -= i;
    37             i *= 2;
    38         }
    39         zero_one_pack(now.amount*now.cost,now.amount*now.weight);
    40     }
    41 }
    42 int main()
    43 {
    44     int t, i, j;
    45     cin >> t;
    46     while(t--)
    47     {
    48          cin >> m >> n;
    49         for(i = 0; i < n; i++)
    50          cin >> th[i].cost >> th[i].weight >> th[i].amount;
    51         for(i = 0; i <= m; i++)
    52          ans[i] = 0;
    53         for(i = 0; i < n; i++)
    54         mulity_pack(th[i]);
    55         cout << ans[m] << endl;
    56     }
    57     return 0;
    58 }

    对应的是背包九讲中的伪代码写的。

    MULTIPLE_PACK(cost,weight,amount)

    if cost * amount >= V

       then COMPLETE_PACK(cost,weight)

              return

    int k ←1 while k < amount

          do 

             ZERO_ONE_PACK(k * cost, k * weight)

            amount  ←  amount - k

            k  ←  k * 2

    ZERO_ONE_PACK(amount * cost, amount * weight)

    刚看到的时候,自己还没反应过来....

    1.当处理到第 i 个物品时,可以得到物品的 cost,weight,amount

    2.如果第 i 个物品的 cost * amount  >= V, 说明可以全部选择第 i 个物品来装满 V 的花费

    3.                     将第 i 个物品当做是完全背包中的一个来处理

    4.如果第 i 个物品不满足 2 的条件, 那么就将第 i  个物品则相当于是进行0/1背包中的一个物品来处理

    5.    将第 i 个物品分成几份,具体的分发就是 K 的变化, 将设分成了m 个数字,则这m个数字可以通过组合得出

           所有的 1--amount 中的数字。 二进制思想体现在这里。然后对这 m 份物品进行0/1背包的处理。

    6.此时的 amount 也是这 m 个数字中的, 也应该进行计算。

    这样就讲所有的都处理完了.....\(^o^)/~

    话说网上搜了挺多的多重背包的代码,但是都是背包九讲的COPY.....

    自己总算看懂......O(∩_∩)O哈哈~

  • 相关阅读:
    时间模块(二)datetime
    xmltodict模块
    C和指针
    C和指针指针
    笔试2
    istream_iterator,ostream_iterator与vector的转换
    C++工厂方法与反射的简单实现
    rpcndr.h和wtypes.h冲突Bug的解决方案
    ubuntu 9.04 安装mysql
    QT in Ubuntu cannot find lfreetype
  • 原文地址:https://www.cnblogs.com/yoru/p/2664061.html
Copyright © 2011-2022 走看看