lintcode最小調整代價
阿新 • • 發佈:2018-10-31
題目:
給一個整數陣列,調整每個數的大小,使得相鄰的兩個數的差不大於一個給定的整數target,調整每個數的代價為調整前後的差的絕對值,求調整代價之和最小是多少。
假設陣列中每個整數都是正整數,且小於等於100。
樣例:
對於陣列[1, 4, 2, 3]和target=1,最小的調整方案是調整為[2, 3, 2, 3],調整代價之和是2。返回2。
解題思路:
欲使|A(i)-A(i+1)|<=target
則A(i+1)-target<=A(i)<=target+A(i+1)
又因為0<=A(n)<=100
所以max(0,A(i+1)-target)<=A(i)<=min(100,target+A(i+1))
由於題目中要求陣列A中每個數都小於等於100,所以我們可以構建一個(n,100)的矩陣Z,Z(i,j)表示A(i)調整為j的花費與A(i-1)調整為j-target<=A(i)<=target+j的最小花費之和。以樣例為例,首先構建一個矩陣Z如下:
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
1 | 1 | 0 | 1 | 2 | 3 |
4 | 4 | 3 | 2 | ||
2 | |||||
3 |
其中Z(1,2)表示A(1)=4調整為1花費與A(0)=1調整為2-1至2+1的最小花費之和,也就是滿足題目要求的前兩個數的最小花費。
程式碼:
public int MinAdjustmentCost(List<Integer> A, int target) { int result = 0; int len = A.size(); if(len <= 1) { return result; } int[][] cost = new int[len][100]; for(int i=0;i<100;i++) { cost[0][i] =Math.abs(A.get(0)-i); } for(int i=1;i<len;i++) { for(int j=0;j<100;j++) { int up = Math.min(99, j+target); int low = Math.max(0, j-target); int diff = Math.abs(A.get(i)-j); cost[i][j] = Integer.MAX_VALUE; for (int k = low; k <= up; k++) { cost[i][j] = Math.min(cost[i][j], cost[i-1][k] + diff); } } } result = Integer.MAX_VALUE; for(int i=0;i<100;i++) { result = Math.min(cost[len-1][i], result); } return result; }