背包系列第六篇----完全背包(求解最大价值的个数)

一:问题

完全背包问题描述:一个容量为V的背包。现在有N种物品,每种物品有无数个,每种物品的体积是C1,C2,…,Cn,对应的每种的价值是W1,W2,…,Wn.。试问,在不超过背包容量的情况下,物品装入背包的最大价值?

和第三篇一样,我们来求出最大价值的个数。

二:分析理解

我们设置num[ i ][ j ]二维数组来表示dp[ i ][ j ]的方案数。

1.dp[ i ][ j ] == dp[ i-1 ][ j ]且dp[ i ][ j ] != dp[ i ][ j-Ci ] + Wi 的时候,num[ i ][ j ] = num[ i-1 ][ j ] ;

2.dp[ i ][ j ] != dp[ i-1 ][ j ]且dp[ i ][ j ] == dp[ i ][ j-Ci ] + Wi 的时候,num[ i ][ j ] = num[ i-1 ][ j-Ci ] ;

3.dp[ i ][ j ] == dp[ i-1 ][ j ]且dp[ i ][ j ] == dp[ i ][ j-Ci ] + Wi 的时候,num[ i ][ j ] = num[ i-1 ][ j ]  + num[ i-1 ][ j-Ci ];

这里可以压缩下num[ i ][ j ],压缩成num[ j ],同dp[ i ][ j ]压缩成dp[ j ]一样。

三:代码

#include<iostream>  
#include<algorithm>  

using namespace std;

#define N 6
#define V 10                         //背包容量

int w[N + 1] = { 0,1,3,1,4,40,5 };    //6个物品的价值,第一个0除外
int v[N + 1] = { 0,4,6,5,1,10,7 };   //6个物品的体积,第一个0除外
int dp[V + 5];
int num[V + 5];

int main()
{
	fill(num, num + V + 5, 1);

	for (int i = 1; i <= N; i++)
	{
		for (int j = v[i]; j <= V; j++)
		{
			if (dp[j] < dp[j - v[i]] + w[i])
			{
				dp[j] = dp[j - v[i]] + w[i];
				num[j] = num[j - v[i]];
			}
			else if (dp[j] == dp[j - v[i]] + w[i])
				num[j] += num[j - v[i]];
		}
	}

	printf("最大价值是:%d\n", dp[V]);
	printf("此时背包的最大价值个数是:%d\n", num[V]);

	return 0;
}
四:数据测试




返回背包系列目录--->背包系列目录





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值