您的位置:首页 > 其它

01背包问题详解

2017-04-28 15:06 253 查看
N个物品,每个物品有一个wi的重量和pi的价值,现在有一个重W的背包问放进物品后的最大值。

//首先是记忆化搜索
//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]]);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: