完全背包问题(动态规划(DP))
来源:互联网 发布:数控铣床编程太阳图案 编辑:程序博客网 时间:2024/06/05 07:27
原题
完全背包问题
有n种重量和价值分别为wi,vi的物品。从这些物品中挑选总重量不超过W的物品,求出挑选物品价值总和的最大值。在这里,每种物品可以挑选任意多件。
1<=n<=100
1<=wi,vi<=100
1<=W<=10000
样例输入
n=3
(w,v)={(3,4),(4,5),(2,3)}
W=7
样例输出
10(0号物品选1个,2号物品选2个)
涉及知识及算法
递推关系:
dp[0][j]=0
dp[i+1][j]=max{dp[i][j-k*w[i]]+k*v[i]|0<=k}
但直接这样去写程序是三重循环,时间复杂度为O(mW^2).
在这个算法中有多余的计算:
在dp[i+1][j]的计算中选择k(k>=1)个 i 物品的情况,与在dp[i+1][j-w[i]]的计算中选择k-1的情况是相同的,所以dp[i+1][j]的递推中k>=1部分的计算已经在dp[i+1][j-w[i]]的计算中完成了。那么可以按照如下方式进行变形:
dp[i+1][j]
=max{dp[i][j-k*w[i]]+k*v[i]|0<=k}
=max(dp[i][j],max{dp[i][j-k*w[i]]+k*v[i]|1<=k})
=max(dp[i][j],max{dp[i][(j-w[i])-k*w[i]]+k*v[i]|0<=k}+v[i])
=max(dp[i][j],dp[i+1][j-w[i]]+v[i])
这样一来就可以用O(nW)时间解决问题。
代码
void solve(){ for(int i=0;i<n;i++) { for(int j=0;j<=W;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]); } } } printf("%d\n",dp[n][W]);}
此外,之前提到的01背包问题和这里的完全背包问题,可以通过不断重复利用一个数组来实现。
01背包问题的情况
void solve(){ for(int i=0;i<n;i++) { for(int j=W;j>=w[i];j--) { dp[j]=max(dp[j],dp[j-w[i]]+v[i]); } } printf("%d\n",dp[w]);}完全背包问题的情况
int dp[MAX_W+1];void solve(){ for(int i=0;i<n;i++) { for(int j=w[i];j<=W;j++) { dp[j]=max(dp[j],dp[j-w[i]]+v[i]); } } printf("%d\n",dp[w]);}注:文章转载自《挑战程序设计竞赛》(第二版)
阅读全文
0 0
- 完全背包问题(动态规划(DP))
- 动态规划之背包问题(二):完全背包问题
- 01背包问题(动态规划DP)
- 01背包问题(动态规划DP)
- 完全背包(动态规划)
- 完全背包(动态规划)
- 动态规划--背包问题(0-1背包,完全背包,多重背包)
- 完全背包问题 动态规划
- 动态规划-完全背包问题
- 完全背包问题-动态规划
- nyoj--311--完全背包(动态规划,完全背包)
- 01背包问题之二 (动态规划(DP))
- 背包问题(dp动态规划思路详解)
- 【动态规划】背包问题 - dp
- DP(动态规划)背包问题
- 动态规划总结(01背包 完全背包 多重背包)
- 动态规划初步( 01 背包、完全背包、多重背包)
- 动态规划背包算法(01背包和完全背包)
- POJ2761 Feed the dogs(treap)
- 推荐一系列优秀的Android开发源码
- scan ip的理解
- 【HDU
- HDUOJ 1874 畅通工程续 Dijkstra算法
- 完全背包问题(动态规划(DP))
- hdu 6119 小小粉丝度度熊(尺取法)
- MATLAB中的常用清除命令有哪些?
- C++中的圓括號重載
- bookstrap 联想下拉框
- PHP之print
- HDU 1863 畅通工程【最小生成树】
- PHP 5 MySQLi 函数
- 2017 HDU 6103 多校联合赛 Kirinriki