您的位置:首页 > 其它

hdoj2191 珍惜现在,感恩生活(01背包 || 多重背包)

2017-12-11 16:54 295 查看

题目链接

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

思路

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

代码

01背包:

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

const int N = 100 * 20 + 10;
int m
, w
;    //记录每袋大米的价格、重量
int dp
;

int main()
{
//freopen("hdoj2191.txt", "r", stdin);
int t;
cin >> t;
while (t--)
{
int n, k;
cin >> n >> k;
int cnt = 0;    //共有cnt袋大米
for (int i = 0; i < k; i++)
{
int p, h, c;
cin >> p >> h >> c;
for (int j = 0; j < c; j++)
{
m[cnt] = p;
w[cnt] = h;
cnt++;
}
}

memset(dp, 0, sizeof(dp));
for (int i = 0; i < cnt; i++)
{
for (int j = n; j >= m[i]; j--)
dp[j] = max(dp[j], dp[j - m[i]] + w[i]);
}
cout << dp
 << endl;
}
return 0;
}

多重背包:

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

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

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
 << endl;
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐