背包算法-记录
一。普通算法 import java.util.Arrays; class Solution { public static void main(String[] args) { new Solution().packages(new int[]{1,3,4},new int[]{1500,2000,3000},4); } public int packages(int[] weight,int[] values,int target){ int x = target; int y = weight.length; int[][] result = new int[y][x+1]; for (int i = 0; i < y; i++) { for (int j = 0; j <= x; j++) { if(j == 0){ result[i][j] = 0; continue; } //第一列的 if(i == 0){ if(weight[i] <= j){ result[i][j] = values[i]; }else{ result[i][j] = 0; } continue; } //后续只需要和上一排对比即可 int topValue = result[i - 1][j]; //判断是否大于当前重量 int wg = weight[i]; //大于的话就是装不下了,直接等于上一排的值即可 if(wg > j){ result[i][j] = topValue; continue; } //重量差值 //着重解释下:这里j - wg是什么意思 //如果大于的话,其实就是比较要这个背包和不要这个背包的值 //要的话,就是values[i]就是当前背包的值 + [j - wg]为剩余背包重量 //然后去上一排中获取这个重量的最大值加起来即可进行比较 int now = result[i - 1][j - wg] + values[i]; result[i][j] = Math.max(now,topValue); } } for (int[] ints : result) { System.out.println(Arrays.toString(ints)); } return result[y-1][x]; } }
二。进阶一维数组
package aa; import java.util.Arrays; class Solution { public static void main(String[] args) { int packages = new Solution().packages(new int[]{1, 3, 4}, new int[]{1500, 2000, 3000}, 4); System.out.println(packages); } public int packages(int[] weight,int[] values,int target){ int x = target; int y = weight.length; /** * 进阶版:只需要一维数组 * 原因:因为我们发现,一个位置的值,只和上一个,和上一排之前的某个值挂钩 * 举例说明 * 0 1 2 3 4 * 1 0 1K 1K 1k 1k * 3 0 1k 1k 1k 只需要[0,4]和3+[0,1]进行比较即可 * 因此其实就是每层从最后一个开始,挂钩的值只会于上一排有关 */ int[] result = new int[x+1]; for (int i = 0; i < y; i++) { for (int j = x; j >= 0; j--) { if(j == 0){ result[j] = 0; continue; } //第一列的 if(i == 0){ if(weight[i] <= j){ result[j] = values[i]; }else{ result[j] = 0; } continue; } //后续只需要和上一排对比即可 int topValue = result[j]; //判断是否大于当前重量 int wg = weight[i]; if(wg > j){ result[j] = topValue; continue; } //重量差值 int now = result[j - wg] + values[i]; result[j] = Math.max(now,topValue); } System.out.println(Arrays.toString(result)); } return result[x]; } }