Find minimum adjustment cost of an array - GeeksforGeeks
http://www.lintcode.com/en/problem/minimum-adjustment-cost/
Given an array of positive integers, replace each element in the array such that the difference between adjacent elements in the array is less than or equal to a given target. We need to minimize the adjustment cost, that is the sum of differences between new and old values. We basically need to minimize ∑|A[i] – Anew[i]| where 0 <= i <= n-1, n is size of A[] and Anew[] is the array with adjacent difference less that or equal to target.
Assume all elements of the array is less than constant M = 100.
http://www.cnblogs.com/EdwardLiu/p/4385819.html
http://www.jiuzhang.com/solutions/minimum-adjustment-cost/
Read full article from Find minimum adjustment cost of an array - GeeksforGeeks
http://www.lintcode.com/en/problem/minimum-adjustment-cost/
Given an array of positive integers, replace each element in the array such that the difference between adjacent elements in the array is less than or equal to a given target. We need to minimize the adjustment cost, that is the sum of differences between new and old values. We basically need to minimize ∑|A[i] – Anew[i]| where 0 <= i <= n-1, n is size of A[] and Anew[] is the array with adjacent difference less that or equal to target.
Assume all elements of the array is less than constant M = 100.
http://www.cnblogs.com/EdwardLiu/p/4385819.html
http://www.jiuzhang.com/solutions/minimum-adjustment-cost/
定义res[i][j] 表示前 i个number with 最后一个number是j,这样的minimum adjusting cost
如果第i-1个数是j, 那么第i-2个数只能在[lowerRange, UpperRange]之间,lowerRange=Math.max(0, j-target), upperRange=Math.min(99, j+target),
这样的话,transfer function可以写成:
for (int p=lowerRange; p<= upperRange; p++) {
res[i][j] = Math.min(res[i][j], res[i-1][p] + Math.abs(j-A.get(i-1)));
}
6 public int MinAdjustmentCost(ArrayList<Integer> A, int target) { 7 // write your code here 8 int[][] res = new int[A.size()+1][100]; 9 for (int j=0; j<=99; j++) { 10 res[0][j] = 0; 11 } 12 for (int i=1; i<=A.size(); i++) { 13 for (int j=0; j<=99; j++) { 14 res[i][j] = Integer.MAX_VALUE; 15 int lowerRange = Math.max(0, j-target); 16 int upperRange = Math.min(99, j+target); 17 for (int p=lowerRange; p<=upperRange; p++) { 18 res[i][j] = Math.min(res[i][j], res[i-1][p]+Math.abs(j-A.get(i-1))); 19 } 20 } 21 } 22 int result = Integer.MAX_VALUE; 23 for (int j=0; j<=99; j++) { 24 result = Math.min(result, res[A.size()][j]); 25 } 26 return result; 27 }https://segmentfault.com/a/1190000004950954
public int MinAdjustmentCost(ArrayList<Integer> A, int target) {
int n = A.size();
int max = 0;
for (int i = 0; i < n; i++) {
max = Math.max(max, A.get(i));
}
int[][] d = new int[n][max+1];
for (int j = 0; j <= max; j++) {
d[0][j] = Math.abs(A.get(0) - j);
}
int curMin = 0;
for (int i = 1; i < n; i++) {
curMin = Integer.MAX_VALUE;
for (int j = 0; j <= max; j++) {
d[i][j] = Integer.MAX_VALUE;
for (int k = Math.max(0, j-target); k <= Math.min(max, j+target); k++) {
d[i][j] = Math.min(d[i][j], d[i-1][k] + Math.abs(A.get(i)-j));
curMin = Math.min(curMin, d[i][j]);
}
}
}
return curMin;
}
http://blog.welkinlan.com/2015/08/14/minimum-adjustment-cost-lintcode-java/Backpack DP problem. Three for loops.
- For each A[i]
- For each possible value curV (1 … 100) that A[i] could be adjusted to.
- For each valid value lastV (1 … 100) that A[i – 1] could be adjusted to (|curV – lastV| < target). Calculate the sum of local adjustment cost:|curV – A[i]| and the accumulative min adjustment cost for A[0 … i] saved in minCost[lastV]
public int MinAdjustmentCost(ArrayList<Integer> A, int target) {
// write your code here
if (A == null || A.size() == 0) {
return 0;
}
int curMinCost[] = new int[101]; //curMinCost[v]: the min cost in A[0..i] if A[i] is changed to v
int lastMinCost[] = new int[101]; //lastMinCost[v]: the min cost in A[0..i - 1] if A[i - 1] is changed to v
//initialize
for (int v = 1; v <= 100; v++) {
curMinCost[v] = Math.abs(v - A.get(0));
}
for (int i = 1; i < A.size(); i++) {
System.arraycopy(curMinCost, 1, lastMinCost, 1, 100);
for (int curV = 1; curV <= 100; curV++) {
curMinCost[curV] = Integer.MAX_VALUE;
for (int lastV = 1; lastV <= 100; lastV++) {
if (Math.abs(curV - lastV) > target) {
continue;
}
curMinCost[curV] = Math.min(curMinCost[curV], lastMinCost[lastV] + Math.abs(curV - A.get(i)));
}
}
}
int min = Integer.MAX_VALUE;
for (int v = 1; v <= 100; v++) {
min = Math.min(min, curMinCost[v]);
}
return min;
}
In order to minimize the adjustment cost ∑|A[i] – Anew[i]| for all index i in the array, |A[i] – Anew[i]| should be as close to zero as possible. Also, |A[i] – Anew[i+1] ]| <= Target.
This problem can be solved by dynamic programming.
Let dp[i][j] defines minimal adjustment cost on changing A[i] to j, then the DP relation is defined by –
dp[i][j] = min{dp[i - 1][k]} + |j - A[i]| for all k's such that |k - j| <= target
Here, 0 <= i < n and 0 <= j <= M where n is number of elements in the array and M = 100. We have to consider all k such that max(j – target, 0) <= k <= min(M, j + target)
Finally, the minimum adjustment cost of the array will be min{dp[n – 1][j]} for all 0 <= j <= M.
int
minAdjustmentCost(
int
A[],
int
n,
int
target)
{
// dp[i][j] stores minimal adjustment cost on changing
// A[i] to j
int
dp[n][M + 1];
// handle first element of array seperately
for
(
int
j = 0; j <= M; j++)
dp[0][j] =
abs
(j - A[0]);
// do for rest elements of the array
for
(
int
i = 1; i < n; i++)
{
// replace A[i] to j and calculate minimal adjustment
// cost dp[i][j]
for
(
int
j = 0; j <= M; j++)
{
// initialize minimal adjustment cost to INT_MAX
dp[i][j] = INT_MAX;
// consider all k such that k >= max(j - target, 0) and
// k <= min(M, j + target) and take minimum
for
(
int
k = max(j-target,0); k <= min(M,j+target); k++)
dp[i][j] = min(dp[i][j], dp[i - 1][k] +
abs
(A[i] - j));
}
}
// return minimum value from last row of dp table
int
res = INT_MAX;
for
(
int
j = 0; j <= M; j++)
res = min(res, dp[n - 1][j]);
return
res;
}