01背包笔记 51nod1085

再次分析一下这个非常经典的动态规划吧~~

 

首先用w[]数组存下每个的重量,v[]数组存下每个的价值,package表示背包的能装下的最大重量。

这里我们把子状态参数设为背包重量和处理的物品序号数。

 

首先说一下递归做法。

定义F(i,L)是背包容量为L,处理到第i个物品时背包中的最大价值。

那么这个状态能从前哪几个状态得到呢?

1.由于容量不够,没有拿第i个物品,从F( i-1,L)这个状态转化过来,总价值不变。

2.容量足够,拿了标号为i的物品,注意这次是从从F(i-1,L-w[i])这个状态转化过来,与原状态相比总价值增加了w[i]。

一共就这个两种状态能转化到F(i,L)。

显然我们要取这两个状态的最大值为F(i,L)。

 

最终想要到第n个物品,背包的容量是L,即(F(n,L))。

 

那么递归过程如下:

//这个只是思路啊,其实递归过程本身就是为了帮我们理清动态规划的。

       

int F(int i,int L)//处理到第i件物品,剩余的空间为L,其返回值是这个状态的能盛下的最大价值。
{
    if(i==0)    return 0;
    int r1=-1,r2=-1;
    if(L>=w[i])//(背包剩余空间可以放下物品 i )
    {
        r1=F(i-1,L-w[i])//第i件物品放入所能得到的价值
    }
 
    r2=F(i-1,L)//第i件物品不放所得到的价值
    return max(r1,r2);//取最大的
}
      

于是噼里啪啦递归下去,到达边界。

边界是 F(0,l)=0 ;

 

显然有好多哦是被重复计算的啦~

那么我们来对他动态规划。

从哪儿到哪儿? 首先我们的状态由是背包的容量和剩下物品数决定的。

本来递归时候是容量从大到小,物品数有少到多进行的。

那么就逆着来啦~

边界是 F(0,L)=0 ,初始状态。

处理顺序从第1个到第n个,

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值