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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/u011956367/article/details/98475755

完全背包:

假设有 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背包问题

猜你喜欢

转载自blog.csdn.net/u011956367/article/details/98475755
今日推荐