1. // 模型1:从左向右尝试模型
    2. /**
    3. * 背包问题
    4. */
    5. public class Code01_Knapsack {
    6. // 所有的货,重量和价值,都在w和v数组里
    7. // 为了方便,其中没有负数
    8. // bag背包容量,不能超过这个载重
    9. // 返回:不超重的情况下,能够得到的最大价值
    10. /**
    11. *
    12. * @param w 货物数组
    13. * @param v 重量数组
    14. * @param bag 背包最大载重
    15. * @return 不超重的情况下能够得到的最大价值
    16. */
    17. public static int maxValue(int[] w, int[] v, int bag) {
    18. // 特殊边界的情况
    19. if (w == null || v == null || w.length != v.length || w.length == 0) {
    20. return 0;
    21. }
    22. // 尝试函数!从0号开始向右选择
    23. return process(w, v, 0, bag);
    24. }
    25. // index 0~N
    26. // rest 负~bag
    27. /**
    28. * 方法1:暴力递归
    29. * @param w 重量
    30. * @param v 价值
    31. * @param index 当前来到index位置
    32. * @param rest 剩余背包容量
    33. * @return
    34. */
    35. // 从左向右尝试,当前来到了index位置。不考虑index之前的信息
    36. public static int process(int[] w, int[] v, int index, int rest) {
    37. // 无效解设置,上游在使用时需要进行判断。
    38. if (rest < 0) { // 背包为0时有可能装的,如规定,重为0 价值100,
    39. return -1;
    40. }
    41. // 越界位置,没有货了
    42. if (index == w.length) {
    43. return 0;
    44. }
    45. // 有货,index位置的货物,bag有空间
    46. // 可能性1:不要当前的货,背包剩余容量变,直接考虑下一个位置
    47. int p1 = process(w, v, index + 1, rest);
    48. // 可能性2:要当前的货
    49. int p2 = 0;
    50. int next = process(w, v, index + 1, rest - w[index]);
    51. // 背包不越界的情况下。
    52. if (next != -1) {
    53. p2 = v[index] + next;
    54. }
    55. return Math.max(p1, p2);
    56. }
    57. /**
    58. * 方式2:动态规划
    59. *
    60. * 根据暴力递归可以发现,动态变化的参数只有 index和rest
    61. * index 的范围为 0-N 在递归中N为 basecase
    62. * rest 的范围为 某个负数 - bag 0 - bag
    63. *
    64. */
    65. public static int dp(int[] w, int[] v, int bag) {
    66. if (w == null || v == null || w.length != v.length || w.length == 0) {
    67. return 0;
    68. }
    69. int N = w.length;
    70. int[][] dp = new int[N + 1][bag + 1];
    71. for (int index = N - 1; index >= 0; index--) { // 从边界开始
    72. for (int rest = 0; rest <= bag; rest++) {
    73. int p1 = dp[index + 1][rest];
    74. int p2 = 0;
    75. int next = rest - w[index] < 0 ? -1 : dp[index + 1][rest - w[index]];
    76. if (next != -1) {
    77. p2 = v[index] + next;
    78. }
    79. dp[index][rest] = Math.max(p1, p2);
    80. }
    81. }
    82. return dp[0][bag];
    83. }
    84. public static void main(String[] args) {
    85. int[] weights = { 3, 2, 4, 7, 3, 1, 7 };
    86. int[] values = { 5, 6, 3, 19, 12, 4, 2 };
    87. int bag = 15;
    88. System.out.println(maxValue(weights, values, bag));
    89. System.out.println(dp(weights, values, bag));
    90. }
    91. }