完全背包问题【动态规划】

本文深入解析了完全背包问题,一种经典的动态规划问题。通过详细解释状态转移方程和提供样例代码,帮助读者理解如何求解最大可装入价值。

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

完全背包:

假设有 n 种物品(每种物品可装入次数不限),至多可装入容积为 m 的容器当中,试问最大可装入的价值为多少?

设w[ i ]为第 i 件物品重量,v[ i ]为第i件物品价值

dp[ i ][ j ]表示将前 i 种物品装入重量 j 的容器当中

状态转移方程:

  1. 当i = 0 或 j = 0时,dp[ i ][ j ] = 0
  2. 当w[ i ] > j时,装不下,dp[ i ][ j ] = dp[ i-1 ][ j ]
  3. 当w[ i ] ≤ j时,设循环变量n,满足n*v[ i ] ≤ j,dp[ i ][ j ] = max( dp[ i ][ j ], dp[ i-1 ][ j-n*w[ i ]] + n*v[ i ] )
  4. 第2、3条可以合并,第2条等价于n=0时第3条的特例

样例输入:

  • 第一行:物品种类n,最大容量m
  • 第二行:每种物品重量
  • 第三行:每种物品价值

3 7
3 4 2
4 5 3

样例输出:

  • 最大可装入价值

10

样例代码:

#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 1001//物品最大数 
#define MAXM 1001//重量最大数 
int dp[MAXN][MAXM];//dp数组 
int w[MAXN],v[MAXN];//重量和价值数组 
int n;//物品数量
int full;//最大可装重量 
void solve();//解题函数 
int main(){
	cin>>n;//输入数量
	cin>>full;//输入重量  
	for(int i=1;i<=n;i++){
		cin>>w[i];//输入重量 
	}
	for(int i=1;i<=n;i++){
		cin>>v[i];//输入价值 
	}
	solve(); 
	return 0;
}
void solve(){
	for(int i=0;i<=n;i++){
		for(int j=0;j<=full;j++){
			if(i==0 || j==0) dp[i][j]=0;//边界dp,结果为0 
			else{
				dp[i][j]=0;//初始0 
				for(int n=0;n*w[i]<=j;n++){
					dp[i][j]=max(dp[i][j],dp[i-1][j-n*w[i]]+n*v[i]);//大小比较 
				}
			}
		}
	}
	cout<<dp[n][full]<<endl;//输出结果 
}

tips:

完全背包同01背包一样,可利用滚动数组进行空间优化,这里不再贴出代码,优化思路详见01背包问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cout0

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

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

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

打赏作者

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

抵扣说明:

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

余额充值