【DP学习】之 01背包
2017-03-06 17:26
274 查看
参考图书《挑战程序竞赛》
![](http://img.blog.csdn.net/20170306171808447?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmFuZmFuNDU2OQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
有些被搜索了两次
![](http://img.blog.csdn.net/20170306172636856?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmFuZmFuNDU2OQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
题目 ->
①普通搜索dfs
最容易想到,但数一大,极容易超时。复杂度(o(2^N))有些被搜索了两次
#include<cstdio> #include<algorithm> using namespace std; #define MAX_N 101 int n, W; //n: 物品数, W: 总重量 int w[MAX_N] = {2, 1, 3, 2}; int v[MAX_N] = {3, 2, 4, 2}; //w:重量,v:价值 int rec(int i, int j){ int res; if(i == n){ //已经没有剩余物品了 res = 0; }else if(j < w[i]){ //无法挑选该物品 res = rec(i + 1, j); }else{ //挑选和不挑选的两种情况都尝试一下 res = max(rec(i + 1, j), rec(i + 1, j - w[i]) + v[i]); } return res; } void solve(){ printf("%d\n", rec(0, W)); } int main(void){ n = 4, W = 5; solve(); return 0; }
②记忆化数组
即用个数组记录,相当于剪枝了,复杂度(o(nW))#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAX_N 101 int n, W; //n: 物品数, W: 总重量 int w[MAX_N] = {2, 1, 3, 2}; int v[MAX_N] = {3, 2, 4, 2}; //w:重量,v:价值 int dp[MAX_N + 1][MAX_N + 1]; //记忆化数组 int rec(int i, int j){ if(dp[i][j] >= 0){ //已经计算过的话直接使用之前的结果 return dp[i][j]; } int res; if(i == n){ res = 0; }else if(j < w[i]) { res = rec(i + 1, j); }else{ res = max(rec(i + 1, j), rec(i + 1, j - w[i]) + v[i]); } //将结果记录在数组中 return dp[i][j] = res; } void solve(){ printf("%d\n", rec(0, W)); } int main(void){ //用-1 表示尚未计算过,初始化整个数组 memset(dp, -1, sizeof(dp)); n = 4, W = 5; solve(); return 0; }
③DP
一步步按顺序求出问题。复杂度(o(nW))#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAX_N 101 int n, W; //n: 物品数, W: 总重量 int w[MAX_N] = {2, 1, 3, 2}; int v[MAX_N] = {3, 2, 4, 2}; //w:重量,v:价值 int dp[MAX_N + 1][MAX_N + 1]; //DP数组 void solve(){ for(int i = n - 1; i >= 0; --i) { for(int j = 0; j <= W; ++j) { if(j < w[i]){ dp[i][j] = dp[i + 1][j]; }else { dp[i][j] = max(dp[i + 1][j], dp[i + 1][j - w[i]] + v[i]); } } } printf("%d\n", dp[0][W]); } int main(void){ //用-1 表示尚未计算过,初始化整个数组 memset(dp, 0, sizeof(dp)); n = 4, W = 5; solve(); return 0; }
相关文章推荐
- POJ 2923 Relocation 状态DP+01背包
- 简单01背包 POJ3211 Washing Clothes 多种衣服分别dp
- POJ 1837 Balance(01背包变形, 枚举DP)
- HDU 2546饭卡(DP:01背包)
- POJ 3628 Bookshelf 2(DP:01背包)
- hdu 2602 DP 01背包
- UVA 624 CD(DP:01背包)
- 01背包 学习笔记 1st
- [HDU] 1561 The more, The Better 树形DP加01分组背包
- HDU 3466 Proud Merchants(DP:01背包+贪心)
- hdu 2955 ( Robberies ) 变相01 背包 DP
- dp之01背包代码
- hdu2126 Buy the souvenirs 01背包变形 dp
- POJ 2923 Relocation(01背包变形, 状态压缩DP)
- hdu1561树形dp 01背包
- DP<01 背包> POJ 1837
- 算法导论学习笔记(十三):动态规划(三):01背包问题
- DP实例之01背包问题C语言实现
- DP 之 SPOJ SCUBADIV (三维 01背包变形)
- HDU 2602 Bone Collector(DP:01背包)