对于背包问题的理解

/*
        背包问题测试:背包问题:给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi 。
                    问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?

            设F[n][c]的值表示可放入的物品最大总价值,i为物品编号,j为当前背包容量.
                        理解:第j件物品是否应该放入背包?
                                1、若当前背包总容量小于第j件物品容量,则不放入。f[i][j] = f[i-1][j]
                                2、若当前物品满足放入背包的条件:j(当前总容量)>wi(物品重量)。
                                则f[i][j] = max(f[i-1][j-wi]+wi,f[i-1][j])

                                惯性思维误区:认为放进第i件物品时一定比前面的总价值大。即错误的认为f[i-1][j-wi]等于f[i-1][j]

                                我的理解:背包问题是从当前的总容量考虑,并非当前的剩余容量。
                                         当确认放进第i件物品时,背包容量立即变为j-wi,然后再从1....i-1中物品中选取,最终得到最大价值
         */
        @Test
    public void BagProblem(){
            final int number = 5;
            final int totalWeight = 20;

            int weight[] = {0,6,4,11,6,9};        //物品重量
            int value[] =  {0,6,3,5,4,6};          //物品价值
            int[][] f = new int[number+1][totalWeight+1];

            for(int j=1;j<=totalWeight;j++){
                for(int i=1;i<=number;i++){
                    if (j<weight[i])
                        f[i][j] = f[i-1][j];
                    else
                        f[i][j] = Math.max(f[i-1][j],f[i-1][j-weight[i]]+value[i]);
                }
            }

            //以下代码输出f数组
            for (int i=1;i<=totalWeight;i++){
                System.out.print("\t\tj="+i);
            }
            System.out.println();
            for (int i=1;i<=number;i++){
                System.out.print("i="+i);
                for (int j=1;j<=totalWeight;j++){
                    System.out.print("\t\t"+f[i][j]);
                }
                System.out.println();
            }
            System.out.println("总重量为:"+f[number][totalWeight]);

    }

 

posted @ 2020-02-06 16:31  、所剩无几  阅读(323)  评论(0编辑  收藏  举报