其他分享
首页 > 其他分享> > 01背包

01背包

作者:互联网

01背包
给定 n 件物品,物品的重量为 w[i],物品的价值为 c[i]。现挑选物品放入背包中,假定背包能承受的最大重量为 V,问应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?
搜索算法
状态i表示考虑第i件物品,v表示当前背包重量,C表示当前最大价值。
dfs(i,v,C)
调用方式dfs(1,V,0)
时间复杂度O(2n)

void dfs(int i,int v,int C)
{
	if (i==n+1)
	{
		if (C>ans) ans=C;
	}
	else
	{
		dfs(i+1,v,C);
		if (v>=w[i]) dfs(i+1,v-w[i],C+c[i]);
	}
}

动态规划

特点是:每种物品仅有一个,可以选择放或不放。
dp[i][v]表示背包承重v 放i件物品时的最大价值。则状态转移方程为:

dp[n][V]为本问题的解

解释
“将前i件物品放入容量为v的背包”这个子问题,若只考虑每i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,此时最大价值为dp[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入容量为v-w[i]的背包中”,此时能获得的最大价值为dp[i-1][v-w[i]]+c[i],显然从这两个策略中选择最大的才是此时的最优,即dp[i][v]=max(dp[i-1][v],dp[i-1][v-w[i]]+c[i])
提高
如果求得选择了哪些物品。
从dp[n][V]开始,如果dp[n][V]==dp[n-1][V]则第n件物品没有被放入,继续从dp[n-1][V]开始考虑…否则第n件物品被放入,继续从dp[n-1][V-w[i]]开始考虑…。
如果内存优化问题
一维数组
分析两维数组的状态转换方程可知dp[i][v]只与dp[i-1][v]和dp[i-1][v-w[i]]有关,可以进行内存优化。
dp[v]表示重量不超过v的最大价值,则dp[v]=max(dp[v],dp[v-w[i]]+c[i]当v>=w[i]时,i表示物品的数量从1~n。
注意遍历的顺序为逆序,这样才能保证推dp[v]时dp[v-w[i]]保存的是状态dp[i-1][v-w[i]]的值。
练习题
P1048 [NOIP2005 普及组] 采药
P1802 5倍经验日
P1510 精卫填海
P2925 [USACO08DEC]Hay For Sale S
P2871 [USACO07DEC]Charm Bracelet S
P2639 [USACO09OCT]Bessie's Weight Problem G
P1926 小书童——刷题大军
P1877 [HAOI2012]音量调节
P3985 不开心的金明(记忆化搜索)

标签:件物品,dfs,01,物品,背包,放入,dp
来源: https://www.cnblogs.com/smghj/p/16033106.html