背包问题:一个给定容量的背包、若干具有一定价值和重量的物品,如何选择物品放入背包的价值最大。其中又分为01背包与完全背包(完全背包指每种物品可以无限件使用)
    思路分析:
    算法的主要思想,利用动态规划来解决。每次遍历到第i个物品,根据w[i]和v[i]来确定是否需要将该物品放入到背包中。即对给定的n个物品,设v[i]、w[i]分别为第i个物品的价值和重量,C为背包的容量。再令v[i][j]表示在前i个物品中能够装入容量为j的背包的最大价值。

    1. 公式:
    2. 1v[i][0] = v[0][j] = 0 // 第一行与第一列为0
    3. // 当准备加入的商品容量大于当前背包的容量时,就直接使用上一个单元格的装入策略
    4. 2) w[i]>j时,v[i][j] = v[i-1][j]
    5. // 当加入的商品小于当前背包的容量时。
    6. // 装入的方式为:v[i-1][j] 上一个单元格的装入的最大量
    7. // v[i]: 表示当前商品价值 v[i-1][j-w[i]]:装入i-1商品到剩余空间j-w[i]的最大值
    8. 3) j>=w[i]时,v[i][j] = max{v[i-1][j], v[i-1][j-w[i]] + v[i]}

    具体的代码实现:

    1. public class KnasackProblem {
    2. public static void main(String[] args) {
    3. // 解决装包的问题
    4. int[] w = {1, 4, 3};
    5. int[] val = {1500, 3000, 2000};
    6. int m = 4; // 背包的容量
    7. int n = val.length;
    8. int[][] v = new int[n+1][m+1];
    9. int[][] path = new int[n+1][m+1];
    10. for(int i=1; i<= n; i++) {
    11. for(int j = 1; j <= m; j ++ ) {
    12. if(w[i-1] > j) {
    13. v[i][j] = v[i-1][j];
    14. }else {
    15. // v[i][j] = Math.max(v[i-1][j], v[i-1][j-w[i-1]] + val[i-1]);
    16. if(v[i-1][j] < v[i-1][j-w[i-1]] + val[i-1]) {
    17. path[i][j] = 1;
    18. v[i][j] = v[i-1][j-w[i-1]] + val[i-1];
    19. }else {
    20. v[i][j] = v[i-1][j];
    21. }
    22. }
    23. }
    24. }
    25. for(int[] num: v) {
    26. System.out.println(Arrays.toString(num));
    27. }
    28. // 输出path
    29. System.out.println("==========================");
    30. int i = path.length -1;
    31. int j = path[0].length - 1;
    32. while(i >= 0 && j >= 0) {
    33. if(path[i][j] == 1) {
    34. System.out.println("装入第" + i + "个物品");
    35. j -= w[i-1];
    36. }
    37. i --;
    38. }
    39. }
    40. }