1268:【例9.12】完全背包问题
【题目描述】
设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。
【输入】
第一行:两个整数,M(背包容量,M≤200)和N(物品数量,N≤30);
第2…N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。
【输出】
仅一行,一个数,表示最大总价值。
【输入样例】
10 4
2 1
3 3
4 5
7 9
【输出样例】
max=12
思路:
完全背包问题在 01问题的基础上加了一个条件,可以使得物品所拿的数量没有限制,所以借助之前二维数组的思想,在j<w[i]的时候,仍然是不能够装上这个物品,采用上一行的数值。但是在j>w[i]的时候,还是需要取一个最大值,但是需要取的是a[i][j - k * w[i]]+k *v[i]的最大值(k取0~j/w[i]),每一种物品不只有取还是不取两个状态,而是有取0个、取1个、取2个等,直到取到j(现在的容量)最多装这个物体的数量(j/w[i])的多个选择,每个选择都需要计算一下,需要选取最大值。
(注意:因为k的不同,用来比较的二维的 j-k*w[i] 对应的上一行的数据就会不同了)
另:01 背包,可参考博客
https://blog.csdn.net/qq_40575034/article/details/103477450
递推公式:
举个例子:假设有5种物品,每种物品无数个,背包容量为10。五种物品的重量依次为{3,2,5,1,6},价值分别为{5,3,6,3,7}.
二维数组分析如图,重点分析了第二种物品那一行。
方式一:
核心代码:(三层for循环)
for(int i=1;i<=n;i++)//n个物体都走一遍
{
for(int j=m;j>=w[i];j--)//j<w[i]时不用变,跟上个物品a[i-1]的数值一样
{
k=j/w[i];//看一下包的容量j能够装下几个物体i
max_z=0;
for(