背包九讲之完全背包问题

背包九讲之完全背包问题

注意事项

        完全背包问题的理解最好建立在01背包的基础之上,01背包http://blog.csdn.net/u013054715/article/details/52402304

问题描述

        有n种物品,每种物品不限量,其中第i种物品的重量为w[i],价值为p[i],现有一容量为v的背包,从这n中物品中任意选取,求解在不超过背包容量的情况下,背包内所放物品总价值的最大值。

问题分析

        完全背包问题与01背包问题的唯一区别在于01背包每种物品只有一件,而完全背包问题每种物品不限量,所以01背包当中第i种物品的取与不取两种状态已不适用与完全背包,完全背包第i种物品存在不取,取1件,取2件。。。取v / w[i]件这v / w[i] + 1种状态,有一种解法是可以把完全背包转换为01背包进行求解,即将第i种物品分解为v / w[i]件物品,这样每件物品就可以用取与不取两种状态表示,进而通过01背包进行递归求解。
        注意:v / w[i]是在假设背包内只存放单一物品的情况下,最多存放v / w[i]件第i种物品,所以尽管每种物品不限量,但是实际可取的件数总不会超过v / w[i]件,所以讲第i种物品分解为v / w[i]件物品即可满足要求。
        转换成01背包的解法再次不再细说,下面介绍另一种解法:
        由题,我们可以想到,由于每种物品不限量,所以每种物品可以抽象的理解成三种状态:
        一、不取,直接跳过第i种物品取判断i - 1种;
        二、取、取完之后去判断第i - 1种;
        三、取、取完之后继续判断第i种物品是否继续取;
        基于以上三种状态进行算法设计。

算法设计

        此处继续使用f[i][v]表示从前i种物品中选取部分物品放入容量为v的背包中总价值的最大值,而上述三种状态分别表示为:f[i - 1][v];f[i - 1][v - w[i]] + p[i];f[i][v - w[i]] + p[i];而f[i][v] = max(f[i - 1][v] , f[i - 1][v - w[i]] + p[i] , f[i][v - w[i]] + p[i]),通过这个状态方程,一直递归下去即可,直到递归到第一种时,使用第一种物品将背包剩余容量进行填充到剩余空间小于第一种物品的重量即可。

java代码

public class Page2 {
    private static int w[] = {2, 3, 5, 1, 3, 2, 7, 4, 2, 6};//重量
    private static int p[] = {4, 6, 7, 1, 4, 8, 3, 6, 2, 4};//价值
    private static int v = 20;
    public static void main(String[] args) {
        System.out.println(fun(w.length - 1, v));
    }
    public static int fun(int i, int v){
        if(i < 1){
            if(v >= w[i]){
                return v / w[i] * p[i];
            }else{
                return 0;
            }
        }else{
            if(v < w[i]){
                return fun(i - 1, v);
            }else{
                return max(fun(i - 1, v), fun(i - 1, v - w[i]) + p[i], fun(i, v - w[i]) + p[i]);
            }
        }
    }
    public static int max(int a, int b, int c){
        return (a > b? a:b) > c ? (a > b? a:b) : c;
    }
}

算法优化

        此算法存在很多可以优化的地方,如1.可以在递归之前使用权重对各种物品进行一次排序;2.当在递归过程中,背包剩余容量小于所有物品中重量最小的物品重量时可以结束递归;3.删除物品中重量相同,价值较小的种类对结果无影响;4.删除物品中权重小且质量可用相对质量小权重大的物品所替代的物品
        以上为我个人对完全背包问题的简单理解,如有不到之处,欢迎指正。
        未完待续。。。

发布了11 篇原创文章 · 获赞 170 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/u013054715/article/details/52403049