• 动态规划(5)----0-1背包


      0-1背包是最基础的背包,一般题目描述为:给定m个物品,其中每个物品的重量用向量W描述,即第一个物品的重量为w1,物品的价值用向量V描述,另外给定一个容量为C的背包,问这个背包中能装下的物品的最大值为多少?

      在这个问题中,有一个显著的特点就是每个物品只能用一次。那么我们分析分析这个问题,在分析问题的时候,为了方便明了,我们假设现在进行到了最后一步(这也是传说中的自顶向下的分析方法),我们假设存在这么一个函数F(n,C) 表示前n个物品放入到容量为C的背包中(这个背包刚好装满)所能获得到最大价值,当我们面对最后一个物品时,我们有两个选择:

      1、将第n个物品丢弃,那么此时就用的最大价值为F(n-1, C)。这个很好理解,第n个丢了嘛,所以不算重量也不算价值。

      2、将第n个物品放入,那么此时的最大价值是Vn+F(n-1, C-Wn)。这个式子也很好理解,Vn表示第n个物品的价值,后面的函数则表征前n-1个物品的价值。可能有同学无法理解背包容量为什么变成了C-Wn,这是因为背包的容量就是C,目前已经装满了,要想将第n个物品放进去,就必须腾出相应的空间,否则第n个物品放不进去。

      在这两个选择下,我们选择受益最大的那个,因此存在一下的递推关系:F(n,C) = max(F(n-1,C), Vn+F(n-1, C-Wn))

      依据上述的递推关系,存在两种实现方式,首先就是动态规划,此外,动态规划可以转换成递归,因此存在两种编码方式。

      首先我们看递归的方式

    public int backpack(int[] value, int[] weight, int index, int C){
            /*结束条件*/
            if(index<0 || C<=0)
                return 0;
    
            /*不放第Index物品*/
            int ans = backpack(value, weight, index-1, C);
            /*放第Index个物品*/
            if(weight[index]<=C){
                ans = Math.max(ans,value[index]+backpack(value, weight, index-1, C-weight[index]));
            }
            /*先算不放的情况,因为不确定是容量是否够,在确定能放进去的情况下,算哪个更优*/
            return ans;
        }

      其次我们看看动态规划的方式

    public int backpackDP(int[] value, int[] weight, int C){
            int[][] dp = new int[value.length][C+1];
            /*容量为0的情况当然是什么都放不下去*/
            for(int i =0;i<value.length;++i)
                dp[i][0] = 0;
    
            for(int i =1;i<value.length;++i){
                /*外层是item, 内层是容量*/
                for(int j=0; j<C;++j){
                    /*不放*/
                    dp[i][j] = dp[i-1][j];
                    if(weight[i]<=j){
                        dp[i][j] = Math.max(dp[i][j], value[i]+dp[i-1][j-weight[i]]);
                    }
                }
            }
            return dp[value.length-1][C];
        }

      两者的代码时很像的,但是,递归明显的计算次数比动态规划多。

  • 相关阅读:
    ssh配置调试的必杀技
    关于lua垃圾回收是否会执行__gc函数呢?
    lua技巧分享之保护执行
    Java访问Hbase
    详解mmseg
    相关query挖掘
    玩转游戏搜索
    JVM系列-常用参数
    Java批处理ExecutorService/CompletionService
    Java动态编译
  • 原文地址:https://www.cnblogs.com/establish/p/12527502.html
Copyright © 2020-2023  润新知