package com.interview.flag.g; import com.interview.utils.ConsoleWriter; /** * Created_By: stefanie * Date: 15-1-1 * Time: 下午5:07 */ public class G17_MinAdjustment { // state: cost[i][v] - the total cost of changing A[i] to v, where v belongs to [0, max] // preValues[i][v] - the i-1 selected value to make cost[i][v] to be the min cost, using to backtrace B[] // init: cost[0][v] = |A[0] - v|; // function: cost[i][v] = min(cost[i-1][v - target ... v + target]) + |A[i] - v| // where v, v - target and v + target all belong to [0, max] // preValues[i][v] = v1 where finally cost[i][v] = cost[i-1][v1] + |A[i] - v|. // result: find the min cost in cost[A.length - 1][v], B[A.length - 1] = v // backtrace B, B[i] = preValues[i+1][B[i+1]] for i from A.length - 2 to 0. public int[] minAdjustment(int[] A, int target){ int max = getMax(A); int[][] cost = new int[A.length][max + 1]; int[][] preValues = new int[A.length][max + 1]; for(int v = 0; v <= max; v++) cost[0][v] = Math.abs(v - A[0]); for(int i = 1; i < A.length; i++){ for(int v = 0; v <= max; v++){ int preCost = Integer.MAX_VALUE; int preValue = 0; for(int diff = -1 * target; diff <= target; diff++){ if(v + diff < 0) continue; if(v + diff > max) break; if(cost[i-1][v+diff] < preCost){ preCost = cost[i-1][v+diff]; preValue = v+diff; } } cost[i][v] = preCost + Math.abs(v - A[i]); preValues[i][v] = preValue; } } int minCost = Integer.MAX_VALUE; int[] B = new int[A.length]; for(int v = 0; v <= max; v++){ if(cost[A.length - 1][v] < minCost){ minCost = cost[A.length - 1][v]; B[A.length - 1] = v; } } for(int i = A.length - 2; i >= 0; i--){ B[i] = preValues[i+1][B[i+1]]; } return B; } private int getMax(int[] num) { int max = 0; for(int i = 0; i < num.length; i ++) if(num[i] > max) max = num[i]; return max; } public static void main(String[] args){ int[] nums = new int[]{1,4,4,3}; G17_MinAdjustment adjustment = new G17_MinAdjustment(); int[] B = adjustment.minAdjustment(nums, 1); //{2,3,4,3} minCost = 2 ConsoleWriter.printIntArray(B); } }