01背包讲解

1. 01背包

背包就是一种动态规划,而动态规划最重要的就是动态转移方程。01背包是背包中最简单的一种,它能解决什么问题呢?

看洛谷的: P1048

简化题意得到:

输入T和M,表示背包容量和物品数量,接下来M行,输入w[i]和 v[i]表示物品的大小和价值,输出背包能装下的最大价值。

  • 30 % 的数据 M≤10

  • 100 % 的数据 M≤100

首先,我们创建一个dp[N][N]的数组,表示一张表格

logo

一开始都赋值成0,竖维枚举物品编号,横维枚举背包大小,dp[i][j]表示当背包容量为jj时,只选前i个物品时的最大值

我们知道,01背包分为不选两种情况,当背包容量+1时,就会分为两种情况:

  • 不选

    那就与只选前i−1个物品一样,只是容量增加了1,所以dp[i][j]的最大价值就是从dp[i−1][j]那里继承下来的,所以我们得到:

    当不选第i−1个物品时

dp[i][j]=dp[i-1][j]
  • 如果你想选第i−1个物品,那你就得看看这时候背包的剩余容量够不够装下它,得到:

if(j>=w[i])

如果成立,此时,你就可以选他了,不过,你的背包容量也变成了j−w[i],但你也可以获得其相应的价值v[i]v[i],而你的背包为j−w[i]的容量时相应的价值就是dp[i−1][j−w[i]],再加上第i个的价值v[i],所以我们得到:

当选第i−1i−1个物品时

dp[i][j]=dp[i−1][j−w[i]]+v[i]

然后我们取最大值:

dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+t[i]);

如果不成立,那我们别无他法,只能不选了,得到:

else
    dp[i][j]=dp[i-1][j];

完整动态转移方程为:

if(j>=w[i]) dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+t[i]);
else dp[i][j]=dp[i-1][j];

核心代码为:

for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(j>=w[i]) dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
			else dp[i][j]=dp[i-1][j];
		}
	}

大家可以尝试完成例题:

P1048

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值