动态规划(二)完全背包问题

       在上一篇文章中,简单分析了0-1背包问题,这篇接着简单分析下完全背包问题。

        完全背包的问题形式如下:有一背包,只能装重量为V的物品,有n个的物品,这些物体体积为w,价值为v,在每个物品最多可以装无线个的情况下,怎么装物品可以让背包中的物品价值最大。完全背包问题与0-1背包相似,不同的是:0-1背包问题汇总,每个物品最多只能装1个;而在完全背包中,每个物品在不超过背包限重的情况下,可以装无数个。因此,完全背包的分析思路与0-1背包类似,不同之处在于状态转移公式的推导。

       与0-1背包问题分析类似,可以先定义一些变量,来辅助分析。具体为:value[ i ]表示第i个物品的价值,weight[ i ]表示第i个物品的体积,dp[ j ]表示当前背包容量为j时,最佳组合对应的价值。为方便分析,设定物品个数为5,背包重量限制为20,示例数据如下:

体积(weight) 2 3 4 5 9
价值(value) 3 4 5 8 10

        分析步骤如下:

           1、如果按照上篇文章的方式做,构建一个二维数组,就需要三层for循环,肯定不是一个好的解决方法。此时可以用一维数组dp[ ]直接来存储value,进而用两层for循环解决该问题。

           2、以dp[ j ],即背包可装重量为j的状态来进行分析(i为物品种类)。此时可能进行的动作有如下几种:

                  1>再装入一件相同物品价值大,即dp[ j ] = dp[ j+1 ];

                  2>再装入一件其他物品价值大,即dp[ j ] = dp[ j-weight[ i ] ] + value[ i ]。

      寻找最大价值的过程,就是不断更新dp数组的过程,直到数组中最后一个值填完,即最大value值。

     Java代码如下:

           static int weight[ ]={0,2,3,4,5,9};       //每个商品容量
           static int value[ ]={0,3,4,5,8,10};       //每个商品价值
           static int NUM = weight.length;         //商品种类。包含第0个这个特殊值
           static int CAP = 21;                           //总可用容量+1,包含第0个这个特殊值,所以总容量是20

            

           //不断填充value数组
           int dp[] = new int[ CAP ];
           for(int i=1;i<NUM;i++){
                for(int j=weight[ i ];j<CAP;j++){
                    dp[ j ] = Math.max(dp[ j ],dp[ j-weight[ i ] ]+value[ i ]);
                }
           }

         //数组最后一个值,即为最大value值
         System.out.println(dp[ 20 ]);

                

原创文章 9 获赞 0 访问量 603

猜你喜欢

转载自blog.csdn.net/m0_37741420/article/details/105210741