/** * Created by itworker365 on 5/10/2017. */ public class DynamicPlan { public static void main (String[] args) { int[] data = {1,-1,3,-5,2,1,9,-1}; // System.out.println(calcMaxSum(data)); int[] a = {1,-1,3,-5,2,1,9,-1}; int[] b = {1,-1,3,-5,2}; Lcs(a, b); // packLoad(); } //最大子段和,如果加上比最大的大,那么就加上,如果加起来是负数,那么就舍弃重置为0 private static int calcMaxSum (int[] data) { int max = data[0]; for (int i = 1; i < data.length ; i++) { int sum = max + data[i]; if (sum > max) { max = sum; } else if (sum < 0){ max = 0; } } return max; } /**0-1(只只能选择放入或者不放入,没有其他可能),指定容量的背包,一堆一定数量和价值的物品,如何能在背包可容纳的情况下找到价值最高的负载方式 * V[i][j]表示前i个物品可以装入容量为j的背包的最大价值 * 可出现以下三种可能: * 1. v[i][0]=v[0][j]=0; 初始状态,背包容量为0或者不装任何物品的时候价值为0 * 2. v[i][j]=v[i-1][j] 当w[i]>j 当放入物品i后背包超重,则无法放入 * 3. v[i][j]=max{v[i-1][j],v[i-1][j-w[i]]+v[i]} 当j>=w[i] 当第i个物品可以放入时,比较不放入 和 放入(减少容量,增加价值) 的价值,选择大的。 * */ private static void packLoad() { int[] weight = {9, 3, 6}; int[] val = {4, 2, 3}; int packMax = 10; int goodsCnt = val.length; Method1(weight, val, packMax, goodsCnt); Method2(weight, val, packMax, goodsCnt); } private static void Method2(int[] weight, int[] val, int packMax, int goodsCnt) { int[] f = new int[packMax + 1]; for(int i = 1; i < f.length; i++){ //初始化为Integer.MIN_VALUE表示必须装满,初始化为0可以不满 f[i] = 0; } for(int i = 0; i < goodsCnt; i++){ for(int j = f.length - 1; j >= weight[i]; j--){ f[j] = Math.max(f[j], f[j - weight[i]] + val[i]); } } for(int i = 0; i < f.length; i++){ System.out.print(f[i] + " "); } System.out.println("Max value: "+f[f.length - 1]); } private static void Method1(int[] weight, int[] val, int packMax, int goodsCnt) { int[][] v = new int[goodsCnt + 1][packMax + 1]; //没带包,装不了 for(int i = 0; i < v.length; i++){ v[i][0] = 0; } //没物品,没得装 for(int i = 0; i < v[0].length; i++){ v[0][i] = 0; } //遍历所有物品 for(int i = 1; i < v.length; i++){ //遍历每个容量单元 for(int j = 1; j < v[0].length; j++){ //当前物品的重量大于背包容量,不放入 if(weight[i - 1] > j) v[i][j] = v[i - 1][j]; else{ //如果放入价值更高,则放入,较少容积增加对应的价值,否则不放入 if(v[i - 1][j] < v[i - 1][j - weight[i - 1]] + val[i - 1]){ v[i][j] = v[i - 1][j - weight[i - 1]] + val[i - 1]; System.out.println("放入X:" + i + " " + j + " " + v[i][j]); }else{ v[i][j] = v[i - 1][j]; } } } } PrintTwo(v); } private static void PrintTwo(int[][] v) { for(int i = 0; i < v.length; i++){ for(int j = 0; j < v[0].length; j++){ System.out.print(v[i][j] + " "); } System.out.println(); } } /** * 最长公共子序列 * c[i][j]表示两个长度分别为i,j的序列的最长公共子序列的长度 * c[0][j] 和 c[i][0]就是一个序列和一个空序列的公共子序列,所以就是空 * 寻找c[i][j]递推关系: * 当序列1的第i个元素和第2个序列的第j个元素相同时,当前最大子序列增加一 c[i - 1][j - 1] + 1 * 当序列1的第i个元素和第2个序列的第j个元素不相同时,当前最大子序列为max(c[i - 1][j], c[i][j - 1]) * */ private static void Lcs(int[] a, int[] b) { int alen = a.length; int blen = b.length; int[][] c = new int[alen][blen]; for (int i = 0; i < c.length; i++) { c[i][0] = 0; } for (int i = 0; i < c[0].length; i++) { c[0][i] = 0; } for (int i = 1; i < c.length; i++) { for (int j = 1; j < c[0].length; j++) { if (a[i - 1] != b[j - 1]) { if (c[i - 1][j] > c[i][j - 1]) { c[i][j] = c[i - 1][j]; } else { c[i][j] = c[i][j - 1]; } } else { c[i][j] = c[i -1][j - 1] + 1; } } } PrintTwo(c); } }