1. 程式人生 > >hdoj2191 珍惜現在,感恩生活

hdoj2191 珍惜現在,感恩生活

() ron set spa val mem amount cin include

題目鏈接

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 }

多重背包:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 20 * 100 + 10;
int m[N], w[N], num[N];
int dp[N];

void zero_one_pack(int weight, int value, int capacity)
{
    for (int i = capacity; i >= weight; i--)    //逆序
        dp[i] = max(dp[i], dp[i - weight] + value);
}

void complete_pack(int weight, int value, int capacity)
{
    for (int i = weight; i <= capacity; i++)    //正序
        dp[i] = max(dp[i], dp[i - weight] + value);
}

void multiple_pack(int weight, int value, int amount, int capacity)
{
    if (weight*amount >= capacity)
        complete_pack(weight, value, capacity);
    else
    {
        int k = 1;
        while (k <= amount)
        {
            zero_one_pack(weight*k, value*k, capacity);
            amount -= k;
            k *= 2;
        }
        zero_one_pack(weight*amount, value*amount, capacity);
    }

}


int main()
{
    //freopen("hdoj2191.txt", "r", stdin);
    int t;
    cin >> t;
    while (t--)
    {
        int n, k;
        cin >> n >> k;
        for (int i = 0; i < k; i++)
            cin >> m[i] >> w[i] >> num[i];

        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < n; i++)
            multiple_pack(m[i], w[i], num[i], n);
        cout << dp[n] << endl;
    }
    return 0;
}

hdoj2191 珍惜現在,感恩生活