三种背包问题

本文深入解析了背包问题的三种类型:0-1背包、完全背包和多重背包,详细介绍了每种类型的算法实现,包括如何通过动态规划求解背包的最大价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背包问题每种物品都有一个价值w、体积c与数量i,你现在有一个背包容积为V, 你想用一些物品装背包使得物品总价值最大.

1. 0-1背包问题

  • 我们有n种物品,物品i的重量为weight[i],价格为value[i]。我们假定所有物品的重量和价格都是非负的。
  • 背包所能承受的最大重量为v。如果限定每种物品只能选择0个或1个,求背包里面能放的最大价格。
static int ZeroOnePackge(vector<int> &weight, vector<int> &value, vector<int> &f, int n, int v)
{
	for (int i = 1; i <= n; i++) //每件物品遍历
		for (int j = v; j >= weight[i]; j--)  //从背包的最大重量到当前物品的重量逆序查找(这样后面的f[i]不会被前面的f[i-1]之类的干扰,新更新的状态也不会影响其他)
			f[j] = max(f[j], f[j - weight[i]] + value[i]);  //后面的式子表示,装上第i件物品前背包内物品的价值+第i件物品的价值
	return f[v];  //返回的为最大容量时的数值
}

2. 完全背包问题

  • 有n种物品和一个容量为v的背包,每种物品都有无限件可用。第i种物品的体重量是weight[i],价值是value[i]。
  • 将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。
static int ZeroMorePackge(vector<int> &weight, vector<int> &value, vector<int> &f, int n, int v)
{
	for (int i = 1; i <= n; i++) //每件物品遍历
		for (int j = weight[i]; j <= v; j++)  //从背包的当前物品到最大重量的重量顺序查找(顺序查找的原因在于考虑之前物品的贡献)
			f[j] = max(f[j], f[j - weight[i]] + value[i]);  //后面的式子表示,装上第i件物品前背包内物品的价值+第i件物品的价值
	return f[v];  //返回的为最大容量时的数值
}

3. 多重背包问题

  • 有n种物品和一个容量为v的背包。第i种物品最多有eachNum[i]件可用,每件体积是weight[i],价值是value[i]。
  • 求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量v,且价值总和最大。
static int MorePackge(vector<int> &weight, vector<int> &value, vector<int> &f, vector<int> &eachNum, int n, int v)
{
	for (int i = 1; i <= n; i++)
		for (int k = 1; k <= eachNum[i]; k++)
			for (int j = v; j >= weight[i]; j--)  //从背包的最大重量到当前物品的重量逆序查找(可通过画图理解)
				f[j] = max(f[j], f[j - weight[i]] + value[i]);  //后面的式子表示,装上第i件物品前背包内物品的价值+第i件物品的价值
	return f[v];  //返回的为最大容量时的数值
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方寸间沧海桑田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值