zoukankan      html  css  js  c++  java
  • hdoj2191 珍惜现在,感恩生活(01背包 || 多重背包)

    题目链接

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

    思路

    由于每种大米可能不止一袋,所以是多重背包问题,可以直接使用解决多重背包问题的方法,也可以将多重背包转化为01背包后求解。

    代码

    01背包:

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 const int N = 100 * 20 + 10;
     8 int m[N], w[N];    //记录每袋大米的价格、重量
     9 int dp[N];
    10 
    11 int main()
    12 {
    13     //freopen("hdoj2191.txt", "r", stdin);
    14     int t;
    15     cin >> t;
    16     while (t--)
    17     {
    18         int n, k;
    19         cin >> n >> k;
    20         int cnt = 0;    //共有cnt袋大米
    21         for (int i = 0; i < k; i++)
    22         {
    23             int p, h, c;
    24             cin >> p >> h >> c;
    25             for (int j = 0; j < c; j++)
    26             {
    27                 m[cnt] = p;
    28                 w[cnt] = h;
    29                 cnt++;
    30             }
    31         }
    32 
    33         memset(dp, 0, sizeof(dp));
    34         for (int i = 0; i < cnt; i++)
    35         {
    36             for (int j = n; j >= m[i]; j--)
    37                 dp[j] = max(dp[j], dp[j - m[i]] + w[i]);
    38         }
    39         cout << dp[n] << endl;
    40     }
    41     return 0;
    42 }

    多重背包:

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 const int N = 20 * 100 + 10;
     8 int m[N], w[N], num[N];
     9 int dp[N];
    10 
    11 void zero_one_pack(int weight, int value, int capacity)
    12 {
    13     for (int i = capacity; i >= weight; i--)    //逆序
    14         dp[i] = max(dp[i], dp[i - weight] + value);
    15 }
    16 
    17 void complete_pack(int weight, int value, int capacity)
    18 {
    19     for (int i = weight; i <= capacity; i++)    //正序
    20         dp[i] = max(dp[i], dp[i - weight] + value);
    21 }
    22 
    23 void multiple_pack(int weight, int value, int amount, int capacity)
    24 {
    25     if (weight*amount >= capacity)
    26         complete_pack(weight, value, capacity);
    27     else
    28     {
    29         int k = 1;
    30         while (k <= amount)
    31         {
    32             zero_one_pack(weight*k, value*k, capacity);
    33             amount -= k;
    34             k *= 2;
    35         }
    36         zero_one_pack(weight*amount, value*amount, capacity);
    37     }
    38 
    39 }
    40 
    41 int main()
    42 {
    43     //freopen("hdoj2191.txt", "r", stdin);
    44     int t;
    45     cin >> t;
    46     while (t--)
    47     {
    48         int n, k;
    49         cin >> n >> k;
    50         for (int i = 0; i < k; i++)
    51             cin >> m[i] >> w[i] >> num[i];
    52 
    53         memset(dp, 0, sizeof(dp));
    54         for (int i = 0; i < n; i++)
    55             multiple_pack(m[i], w[i], num[i], n);
    56         cout << dp[n] << endl;
    57     }
    58     return 0;
    59 }
  • 相关阅读:
    【题解】 bzoj1207: [HNOI2004]打鼹鼠 (动态规划)
    【题解】 bzoj1088: [SCOI2005]扫雷Mine (神奇的做法)
    【题解】 bzoj4472: [Jsoi2015]salesman (动态规划)
    【题解】 bzoj4033: [HAOI2015]树上染色* (动态规划)
    【题解】 [HNOI/AHOI2018]道路 (动态规划)
    炫酷的英文字体分享
    艾伦·麦席森·图灵
    历史上最知名的15位计算机科学家
    浏览器首页被改为2345之解决方法
    linux命令缩写及全称
  • 原文地址:https://www.cnblogs.com/sench/p/8023914.html
Copyright © 2011-2022 走看看