完全背包

之前我讲过0-1背包,这里讲解完全背包。

一. 问题描述

假设我们给定n个物品,每个物品具有重量weight以及价值value,第i个物品的重量为weight[i], 价值为value[i]。同时给定一个容量为m的背包,求解背包里装入的物品价值之和的最大值。

不同于0-1背包问题(每件物品最多放入一次),多重背包可以放入每件物品无数次,只要满足背包的容量限制。

二. 分析

利用跟0-1背包相同的分析思路,我们考虑第i件物品:放入或者不放。如果不放,那么dp[i][j]=dp[i-1][j]; 如果放入,那么dp[i][j]=dp[i][j-weight[i]]+value[i]. 这里是跟0-1背包不同之处。这一次我们放入了i,之前的则是

dp[i][j-weight[i]]

我们用了前i种物品,至于放没放入物品i我们不知道,有可能没放,也可能放了很多次。整合起来,状态转移方程是

dp[i][j]=max{dp[i-1][j], dp[i][j-weight[i]]+value[i]}.

示意图如下:

优化存储空间,我们可以得到新的状态转移方程

dp[j]=max{dp[j], dp[j-weight[i]]+value[i]}.

 可以看到这个方程与0-1背包的完全相同,但是意义是不一样的!反应在代码上

memset(dp,0,sizeof(dp)); 
for(i=0; i<n; i++)
    for(j=weight[i]; j<=m; j++)
        dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);

差别在于j是升序。参考上图很容易理解,与0-1背包的分析是同样的思路,这里不再赘述。

参考了以下博文:

https://blog.csdn.net/qq_38984851/article/details/81133840

posted on 2019-03-04 16:18  小叶子曰  阅读(747)  评论(0编辑  收藏  举报

导航