01背包、完全背包证明(合理+简洁)

这里只提供合理性证明,有关知识和代码原理全网可以找到很多可以学习的地方,我就不再赘述。但是有关证明就很难找到了,尤其一些说是证明,但是都是在叙述方法的过程(还是在说方法),所以这里提供我个人对于这个方法的证明。

//0/1背包代码:
for(int i=0;i<n;i++)//n个物品 
{
	for(int j=V;j>0;j--)//体积 
	{
		if(j>=v[i])dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
		else break;
	}
}

首先对于0/1背包,我们先假设背包体积为V,最优解为E,而E中含有某个物品为A(体积为v,价值为w),那么 V - v 的最优解也一定是 E - A 。证明:反证法,假设 E - A 不是 V - v 的最优解,那么假设 V - v 的最优解为F,则F的价值大于 E - A 的价值,那么 F + A 肯定可以是V的一种选择,而它的价值则高于E,E不是最优解,矛盾,因此 V - v 的最优解也一定是 E - A 。

那么利用上面这一条件我们就能大大减少罗列次数(如果不考虑时间复杂度的话也一定可以暴力枚举出结果,但时间复杂度为O(n^2),dp实际上也是为了减少罗列,时间复杂度O(n*V))。上面代码中可以看出,n个物品是注意加入考虑范围的,而且每次 j 是从后往前的,所以每次如果有把第i个物品加入也只会加入一次,属于可行范围内( j 反过来就不是了)。而在这些可行范围内,我们必将罗列出最优解。首先设最优为{x1, x2, x3, x4}(x1的体积为v1,价值为w1,其他同理;其中xi并不一定是n个物品中的第i个,只是表示其在最优解中按照物品顺序的编号),那么根据上面推出的结论,{x1, x2, x3}就是 V - v4 的最优解,那么在遍历到物品x3时,且 j 为 V - v4 的时候,假设前面dp[V-v3-v4]已经得出正确结果为w1+w2,那么此时就会得出dp[V - v4]=w1+w2+w3(因为是在可行范围内罗列,而这个是最优解,没人可以更新它),x4的加入也是同理,而基础情况就是dp[0]=0,也是成立的,那么由数学归纳法(衔接处和基础情况都成立)就证明了罗列方法的合理性。

//完全背包 
for(int i=0;i<n;i++)
{
	for(int j=v[i];j<=V;j++)
	{
		dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
	}
}

完全背包也是同理,把所有相同种类的不同物品也都看为不同物品,那么也可以利用最上面的结论,假设最优解为{x1, x1, x2, x2, x2, x3, x3, x4, x4, x4},那么在遍历到物品x3且体积 j 为 V - 3*v4 - v3时,同样假设前面 V - 3*v4 - 2*v3 得出的是最优解{x1, x1, x2, x2, x2},那么此时加入也是x3,后面的其他物品也同理,而基础情况也同上,因为各种物品的数量都是无限的,因此上面代码所罗列到的都是合理的装包操作,而且肯定能罗列到最优解。

综上所述,dp方法的合理性在于能减少罗列次数,并且罗列的情况保证在合理的范围内,而且这个范围还必然地包含最优解,所以最后一定能获得最优解。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值