完全背包问题
来源:互联网 发布:软件有实体么 编辑:程序博客网 时间:2024/05/29 16:11
Problem:
有n种重量分别为wi,vi 的物品。从这些物品中挑选出总重量不超过W的物品,求出挑选物品价值总和的最大值。在这里,每种物品可以挑选任意多件。
Input:
n=3
(w,v)={(3,4)(4,5)(2,3)}
w=7
Output:
10 (0号物品选1个,2号物品选2个)
Hint:
令d[i][j]:=从前 i 种物品中挑选总重量不超过 j 时总价值的最大值。
那么递推关系为:
dp[0][j] = 0
dp[i+1][j] = max(dp[i][j], dp[i+1][j-w[i]]+v[i])
代码如下:
#include<iostream>#include<fstream>#include<vector>#include<string>#include<map>#include<iterator>#include<algorithm>#include<numeric>#include<cmath>#include<sstream>#include<bitset>using namespace std;const int MaxN = 501;const int MaxW = 10001;int dp[MaxN][MaxW];vector<int> w;vector<int> v;int main(){#ifdef ONLINE_JUDGE#else freopen("D:\\in.txt", "r", stdin); freopen("D:\\out.txt", "w", stdout);#endif // ONLINE_JUDEG int n(0); int m(0); memset(dp, 0, sizeof(dp)); scanf("%d%d", &n, &m); int weight(0), value(0); for (int i = 0; i < n; i++) { cin >> weight >> value; w.push_back(weight); v.push_back(value); } for (int i = 0; i <n; i++) { for (int j = 0; j <=m; j++) { if (j < w[i]) { dp[i + 1][j] = dp[i][j]; } else { dp[i + 1][j] = max(dp[i][j], dp[i+1][j - w[i]] + v[i]); } } } cout << dp[n][m] << endl; return 0;}
此外,此前提到的01背包问题和这里的完全背包问题,可以通过不断重复利用一个数组来实现。
01背包问题的情况:
int dp[MaxW + 1];void solve(){ for (int i = 0; i<n; i++) for (int j = m; j >= w[i]; j--) { //放入和不放入的情况都尝试一下,注意循环方向 dp[j] = max(dp[j], dp[j - w[i]] + v[i]); } cout << dp[m] << endl;}
多重背包的情况:
int dp[MaxW + 1];void solve(){ for (int i = 0; i<n; i++) for (int j = w[i]; j <=m; j++) { //放入和不放入的情况都尝试一下,注意循环方向 dp[j] = max(dp[j], dp[j - w[i]] + v[i]); } cout << dp[m] << endl;}
像这样书写的话,两者的差异就变成只有循环的方向了。重复利用数组虽然可以节省内存空间,但使用不好的将有可能留下bug,所以要格外小心。不过出于节约内存的考虑,有时候必须要重复利用数组,也存在通过重复利用能够进一步降低复杂度的问题。
重复利用数组的解法如下:
#include<iostream>#include<fstream>#include<vector>#include<string>#include<map>#include<iterator>#include<algorithm>#include<numeric>#include<cmath>#include<sstream>#include<bitset>using namespace std;const int MaxN = 501;const int MaxW = 10001;int dp[MaxW + 1];vector<int> w;vector<int> v;int main(){#ifdef ONLINE_JUDGE#else freopen("D:\\in.txt", "r", stdin); freopen("D:\\out.txt", "w", stdout);#endif // ONLINE_JUDEG int n(0); int m(0); memset(dp, 0, sizeof(dp)); scanf("%d%d", &n, &m); int weight(0), value(0); for (int i = 0; i < n; i++) { cin >> weight >> value; w.push_back(weight); v.push_back(value); } for (int i = 0; i <n; i++) { for (int j = w[i]; j <= m;j++) { dp[j] = max(dp[j], dp[j - w[i]] + v[i]); } } cout << dp[m] << endl; return 0;}
0 0
- 背包问题-完全背包-背包问题
- 01背包 完全背包问题
- 背包问题2:完全背包
- 01背包+完全背包问题
- nyoj311完全背包(完全背包问题)
- 完全背包问题
- 完全背包问题
- 完全背包问题
- 完全背包问题
- 完全背包问题
- P02: 完全背包问题
- 完全背包问题、、、
- P02: 完全背包问题
- 完全背包问题
- P02: 完全背包问题
- 完全背包问题
- P02: 完全背包问题
- 完全背包问题总结
- 怎么去拥有一夏天的风~
- 6174问题
- Winform复习之记事本
- 哈希的构造,处理冲突和查找
- TCP/IP,http,socket,长连接,短连接——小结。
- 完全背包问题
- JDBC基础实现
- 让IE支持css3
- TCP协议疑难杂症全景解析
- 对标准库容器的扩展:Variant/tuple
- 第一周(项目三)——日期结构体。
- SQL学习_脉络图总结_2014.3.2
- java 线程状态转换
- Bash脚本的两种执行方式