zoukankan      html  css  js  c++  java
  • 动态规划 背包九讲的实现。

    最近在学习动态规划,会了不少基础的之后就开始挑战比较困难的背包问题了,我这里自己写了每一讲的问题,解析,代码,注释。如果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
    ",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吧。

  • 相关阅读:
    POJ1182 食物链---(经典种类并查集)
    HDU1025---(LIS 最长上升子序列 的应用)
    HDU5748---(记录每个元素的 最长上升子序列 nlogn)
    c++ 批量初始化数组 fill和fill_n函数的应用
    JNI 方法注册与签名+BufferedReader使用readLine问题
    正确在遍历中删除List元素
    Head First Java设计模式思维导图总结
    关于一些基础的Java问题的解答(七)
    关于一些基础的Java问题的解答(六)
    关于一些基础的Java问题的解答(四)
  • 原文地址:https://www.cnblogs.com/luyi14/p/4358930.html
Copyright © 2011-2022 走看看