物品无限的背包问题。有nn种物品,每种均有无穷多个。第i种物品的体积为ViVi,重量为WiWi。选一些物品装到一个容量为CC的背包中,使得背包内物品在总体积不超过CC的前提下重量尽量大。
记忆化搜索法:
#define INF 100
#include<algorithm>
#include<iostream>
using namespace std;
int c = 10,n=3;
int d[INF]; //d[s]代表此体积能装的最大重量
int v[3] = { 1,3,5 };
int w[3] = { 1,7,8 };
int dp(int s)
{
int i;
if (d[s] != -1) {
return d[s];
}
d[s] = 0;
for (i = 0; i < n; i++) {
if (s >= v[i]) {
d[s] = max(d[s], dp(s - v[i]) + w[i]);
}
}
return d[s];
}
void print_ans(int s)
{
int i;
for (i = 0; i < n; i++) {
if (s >= v[i] && (d[s] == d[s - v[i]] + w[i])) {
cout << v[i] << " ";
print_ans(s - v[i]);
break;
}
}
}
int main()
{
memset(d, -1, sizeof(d));
int i, j,ans=-1;
for (i = 0; i < n; i++) {
d[c] = max(d[c], dp(c-v[i])+ w[i]);
}
cout <<"能装的最大重量为:"<< d[c] <<endl;
cout << "装的体积种类:"; print_ans(c);
return 0;
}
结果:

还有一种是递推法,打印最小字典序时用空间换取了时间,在硬币那节有讲到
#define INF 100
#include<algorithm>
#include<iostream>
using namespace std;
int c = 10,n=3; //c是体积
int maxw[INF]; // maxw[s]代表此体积能装的最大重量
int maxw_coin[INF];
int v[3] = { 1,3,5 };
int w[3] = { 1,7,8 };
void print_ans(int s)
{
while (s) {
cout << maxw_coin[s]<<" ";
s = s - maxw_coin[s];
}
}
int main()
{
memset(maxw, -INF, sizeof(maxw));
maxw[0] = 0; //给出出口
int i, j;
for (i = 1; i <= c; i++) {
for (j = 0; j < n; j++) {
if (i >= v[j]) {
if (maxw[i] < maxw[i - v[j]] + w[j]) {
maxw[i] = maxw[i - v[j]] + w[j];
maxw_coin[i] = v[j];
}
}
}
}
cout <<"能装的最大重量为:"<< maxw[c] <<endl;
cout << "装的体积种类:"; print_ans(c);
return 0;
}
结果相同
2465

被折叠的 条评论
为什么被折叠?



