java 完全背包问题算法_算法笔记(c++)--完全背包问题

算法笔记(c++)--完全背包和多重背包问题

完全背包

完全背包不同于01背包-完全背包里面的东西数量无限

假设现在有5种物品重量为5,4,3,2,1

价值为1,2,3,4,5

背包容量为10

#include #include

using namespacestd;intmain()

{int total_weight = 10;int w[6] = { 0,5,4,3,2,1};int v[6] = { 0,1,2,3,4,5};int dp[11] = { 0};for (int i = 1; i <= 5; i++)for (int j = w[i]; j <= 10;j++)

dp[j]= max(dp[j],dp[j - w[i]] +v[i]);

cout<< "总的价值为:" << dp[10] <

}

其他都和01背包一样,就是遍历j时候的初始化不一样。

这里的dp[j]还是表示前i件物品放入一个为j容量的背包获得的最大价值,每次更新必然保证是当前最优解。就像求最长递增子序列一样。都是把所有情况过一遍然后拿最大的结果。

不多讲直接推算几步就全懂了。

1)首先是当只有物品1号的时候,j初始化为1号物品的重量为5

dp[5]=max(dp[5],dp[5-5]+1]=1

dp[6]到dp[9]都是1,dp[10]=2

2)然后现在是有物品1号和2号,j初始化为2号物品重量4

dp[4]=max(dp[4],dp[4-4]+2)=2

dp[5]=max(dp[5],dp[5-4]+2)=2

dp[..8]=max(dp[8],dp[8-4]+2)=4

其实到这里也差不多了,下面都是一样的。

我们要决定是不是要放这个物品,就从这个物品的大小出发遍历背包容量,然后每次遍历都对比下假如现在腾出这个物品的空间并且放进去比原来的价值还大的话,就放进去。

区别------------01背包和完全背包

01背包遍历是反向的,这样更新就不会影响前面的。

而完全背包正向遍历,会改变前面的所以也就可出现多次存放的了。

多重背包

多重背包再加点限制,数量有限制。

数据如下:

数量

重量

价值

0

0

0

1

5

1

2

4

2

1

3

3

2

2

4

1

1

5

同样设背包为10大小

代码如下:

#include #include

using namespacestd;intmain()

{int total_weight = 10;int w[6] = { 0,5,4,3,2,1};int v[6] = { 0,1,2,3,4,5};int cot[6] = { 0,1,2,1,2,1};int dp[11] = { 0};for (int i = 1; i <= 5; i++)for (int k = 1; k <= cot[i];k++)for (int j = 10; j >= w[i]; j--)

dp[j]= max(dp[j], dp[j - w[i]] +v[i]);

cout<< "总的价值为:" << dp[10] <

}

这次不一步步来了,懂01就可以了。

因为每次01都是放一个而完全背包是放多个,我们也不知道完全 背包放了几个。所以多重背包算是01背包的变种。

既然我们每次遍历都是判断放不放这一个物品,那我们干脆就有几个就遍历几遍。再遍历外面再加一个for就好了

很好理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值