动态规划--背包问题,带习题

来源:互联网 发布:怎么修改淘宝追加评价 编辑:程序博客网 时间:2024/05/29 14:33

背包问题

有编号分别为a,b,c,d,e的五件物品,它们的重量分别是4,5,6,2,2,它们的价值分别是6,4,5,3,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

分析:

nameweightvalue012345678910a4600006666666b540000666661010c650000666661011d230033669991011e260066991212151515

a2表示只有物品a时,承重为2的背包最大价值为0;b2表示只有物品a,b时,承重为2的背包最大价值为0.同理c2=0,d2=3,e2=6

a3~e3,a4~c4的值也很容易得出,那么d4为多少呢?

d4表示只有abcd四种物品时承重为4的背包的最大价值,可以把这种情况下的包发分为两类

①不装d,则只能包装abc,此时最大价值=c4=6

②装d,背包的承重4减去d的重量2,则剩下重量为2来装abc,此时最大价值为物品d的价值+c2=3

两者取其大,d4 = Max{c4,c[4-weight(d)]+value(d)}= 6

进一步,我们用i=0表示只有物品a的情况,用i=1表示只有物品ab的情况...用i=4表示有abcde的情况,

则我们可以用f[i,j](i=0,1,2,3,4)分别表示承重为j的背包的最大价值

不难得出:当j>=weight[i]时 f[i,j] = Max{ f[i-1,j] , f[i-1,j-weight[i]]+value[i] }

                    当j<weight[i]时 f[i,j] = f[i-1,j]


java代码:

          public void bag(int[] weights, int[] values, int bagsize){int[][] result = new int[weights.length][bagsize+1];for(int i=0;i<bagsize+1;i++){for(int j=0;j<weights.length;j++){if(i==0){result[j][i] = 0;System.out.print(result[j][i]+" ");continue;}else if(j==0){if(weights[j]<=i){result[j][i] = values[j];}else{result[j][i] = 0;}}else{if(weights[j]<=i){result[j][i] = result[j-1][i-weights[j]]+values[j]>result[j-1][i]?result[j-1][i-weights[j]]+values[j]:result[j-1][i];}else{result[j][i] = result[j-1][i];}}}}for(int m=0;m<weights.length;m++){for(int n=0;n<bagsize+1;n++){System.out.print(result[m][n]+" ");}System.out.println("");}}
测试代码:

      public static void main(String[] args){int[] weights = {4,5,6,2,2};int[] values = {6,4,5,3,6};MyTest test = new MyTest();test.bag(weights, values, 10);      }

练习题:

计算n个节点的查询二叉树有多少种?

原题链接 https://leetcode.com/problems/unique-binary-search-trees/

答案稍后放入评论


1 0