01背包问题详解
2017-04-28 15:06
253 查看
N个物品,每个物品有一个wi的重量和pi的价值,现在有一个重W的背包问放进物品后的最大值。
基于上面的思想我们有递推式dp[i][j]={max(dp[i−1][j],dp[i−1][j−w[i]]+p[i])dp[i−1][j](j >=w[i] )(j < w[i])
根据递推式有
这样的话时间复杂度和空间复杂度都是O(nW) 可以对空间复杂度进行优化有
dp[j]=max(dp[j],dp[j−w[i]]+p[i]) 每一次获取dp[j] 都必须要只知道 前一次的 dp[j] 和 dp[j-w[i]]
//首先是记忆化搜索 //dp[i][j] 在前i件物品里面选择不超过重量j的最大价值 int rec(int i, int j) { if(dp[i][j] >= 0) //在此之前需要memset(dp, -1, sizeof(dp)) return dp[i][j]; int res; if(i == n) res = 0; //没有物品选择了 else if(j < w[i]) //当前重量无法装下第i件物品 res = rec(i + 1, j); else res = max(rec(i + 1, j), rec(i + 1, j - w[i]) + p[i]); return res = dp[i][j]; }
基于上面的思想我们有递推式dp[i][j]={max(dp[i−1][j],dp[i−1][j−w[i]]+p[i])dp[i−1][j](j >=w[i] )(j < w[i])
根据递推式有
int ZeroOnePack() { memset(dp, 0, sizeof(dp)); for(int i = 0; i < n; ++i) for(int j = 0; j <= W; ++j) dp[i + 1][j] = j >= w[i]? max(dp[i][j], dp[ bb93 i][j - w[i]] + p[i]) : dp[i][j]; return dp [W]; }
这样的话时间复杂度和空间复杂度都是O(nW) 可以对空间复杂度进行优化有
dp[j]=max(dp[j],dp[j−w[i]]+p[i]) 每一次获取dp[j] 都必须要只知道 前一次的 dp[j] 和 dp[j-w[i]]
for(int i = 0; i < n; ++i) for(int j = W; j >= w[i]; --j) dp[j] = max(dp[j], dp[j-w[i]]);