0-1背包

1.问题描述
有n件物品和一个最大能背m重量的背包。其中,第i件物品的重量为wight[i],相对应的价值为value[i]。物品不能重复使用。试问,怎样放置物品可使得价值最大?
2.解决方案
使用动态规划方法进行求解。
(1)确定dp含义
dp[i][j]表示从[0-i]的物品中进行一次动作选择,放到容量为j的背包中,所获取的最大价值。
(2)状态转移方程
0-1背包的动作可分为两种:向背包中放入物品和不放入物品。因此:

dp[i][j]=max(dp[i-1][j-wight[i]]+value[i],dp[i-1][j]);

(3)初始化边界
需要对dp[i][0]和dp[0][j]进行初始化。
其中dp[0][j]的初始化应注意只能从后往前;如果从前往后会出现重复计算,例如:dp[0][2]=dp[0][1]+value[2]。

for(int j=bagwight; j>=wight[0];j--){
	dp[0][j]=dp[0][j-wight[0]]+value[0];
}

(4)确定遍历顺序
1.先遍历背包,再遍历物品
2.先遍历物品,再遍历背包
(5)代码

int bag_problem(){
	vector<int>wight={1,3,4};
	vector<int>value={10,15,30};
	int bagwight=4;
	
	vector<vector<int>>dp(wight.size(), vector<int>(bagwight+1, 0));
	for(int j=bagwight; j>=wight[0];j--){
		dp[0][j]=dp[0][j-wight[0]]+value[0];
	}

	for(int j=1;j<=bagwight;++j){
		for(int i=1;i<wight.size();++i){
			if(j<wight[i]) dp[i][j]=dp[i-1][j];
			else dp[i][j]=max(dp[i-1][j-wight[i]]+value[i],dp[i-1][j]);
		}
	}

	return dp[wight.size()-1][bagwight];
}

3.使用一维数组解决0-1背包问题
(1)确定dp含义
dp[j]表示容量为j的背包的最大价值
(2)状态转移方程
dp[j]=max(dp[j], dp[j-wight[i]]+value[i])
(3)初始化

for(int j=0; j<=bagwight;++j){
	dp[j]=0;
}

(4)遍历顺序
一维数组中,背包的遍历必须由大到小;保证一件物品放一次。

for(int i=0;i<wight.size();++i){
	for(int j=bagwight;j>=wight[i];--j){
		dp[j]=max(dp[j], dp[j-wight[i]]+value[i]);
	}
}

在二维dp数组中,先物品后背包,和先背包后物品,均可以。
在一维dp数组中,必须先遍历物品,后遍历背包。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值