动态规划 背包九讲的实现。

最近在学习动态规划,会了不少基础的之后就开始挑战比较困难的背包问题了,我这里自己写了每一讲的问题,解析,代码,注释。如果dp还没入门的孩纸就去看看我的另一篇文章http://www.cnblogs.com/luyi14/p/4344946.html    

第一讲  0  1  背包

题目:

有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

解析:

最基础。

状态:0不装1装,是0 1 背包

转移方程:f[i][v] = max (f[i][v],f[i-1][v-c[i]]+w[i]);

一开始都看不懂这是什么玩意。变成一维的会好理解一点。看代码:

 1 #include<stdio.h>
 2 #define max(a,b) a>b?a:b
 3 int main()
 4 {
 5     int v,n;
 6     while(~scanf("%d%d",&v,&n))
 7     {
 8         int c[101]={0},w[101]={0},f[1001]={0},i,j,k;
 9         //这里定义初始值也是为了解决另一种问题就是恰好装满背包
10         //初始值就是除了f【0】=0.别的均-无穷就好
11         //已经不用吧背包装满。就如上代码
12         for(i = 1 ; i <= n ; i ++)
13             scanf("%d%d",&c[i],&w[i]);
14         for(i = 1 ; i <= n ; i++)
15             //
16             for(j = v;j >= c[i]; j--)
17         //优化 后面获得的数值不会影响到前面的这是肯定的、
18                 f[j] = max(f[j],f[j-c[i]]+w[i]);
19         //等于转移方程 f[v] = max(f[i-1][v],f[i-1][v-c[i]);
20         printf("%d\n",f[v]);
21     }
22     return 0;
23 }

稍微先看看代码再来看解析:

刚才的方程式非常重要建议要彻底理解,将前i 件物品放入容量为v 的背包中,这个子问题,如果只考虑第i件物品 的策略 (0 1)那么问题就简化为前i -1 件物品放入的问题,(这里算是递归的思路吧不断缩短)前i - 1个物体放入剩下容量为 v - c【i】 的背包中  这时候的最大价值就是

f[i][v-c[i]] 加上第i件物品的价值w[i];

这个确实很难理解。看看一维的代码吧。

for i=1..N

    for v=V..0

        f[v]=max{f[v],f[v-c[i]]+w[i]};

这里就是用f【】来保存每一个物品放不放所导致的结果,

话就不多说了。还是自己把过程模拟一遍,才能真正去理解算法中精妙的dp吧。

 

posted on 2015-03-23 09:34  陆熠十四  阅读(551)  评论(0编辑  收藏  举报

导航