您的位置:首页 > 其它

lintcode:Minimum Adjustment Cost

2016-04-06 19:47 246 查看
Given an integer array, adjust each integers so that the difference of every adjacent integers are not greater than a given number target.
If the array before adjustment is A, the array after adjustment is B, you should minimize the sum of
|A[i]-B[i]|


Have you met this question in a real interview?

Yes


Notice


You can assume each number in the array is a positive integer and not greater than
100
.

Example

Given
[1,4,2,3]
and
target =
1
, one of the solutions is
[2,3,2,3]
,
the adjustment cost is
2
and it's minimal.
Return
2
.

Tags

转自http://www.cnblogs.com/yuzhangcmu/p/4153927.html

这道题真的惭愧,确实没有想出来

可以用递归和动态规划来解决这道题

递归,有点像word ladder和数独一样代码如下

/**
* @param A: An integer array.
* @param target: An integer.
*/
public static int MinAdjustmentCost1(ArrayList<Integer> A, int target) {
// write your code here
if (A == null) {
return 0;
}

return rec(A, new ArrayList<Integer>(A), target, 0);
}

/*
* SOL 1:
* 最普通的递归方法。
* */
public static int rec(ArrayList<Integer> A, ArrayList<Integer> B, int target, int index) {
int len = A.size();
if (index >= len) {
// The index is out of range.
return 0;
}

int dif = 0;

int min = Integer.MAX_VALUE;

// If this is the first element, it can be from 1 to 100;
for (int i = 0; i <= 100; i++) {
if (index != 0 && Math.abs(i - B.get(index - 1)) > target) {
continue;
}

B.set(index, i);
dif = Math.abs(i - A.get(index));
dif += rec(A, B, target, index + 1);
min = Math.min(min, dif);

// 回溯
B.set(index, A.get(index));
}

return min;
}


更好的解法用动态规划,dp[i][[j] i表示现在loop到的位置,j表示1-100的数字,dp[i][j]表示,当loop到i位置时,取j值时整个修改的最小值

所以最终的结果要 比较 dp[A.size()-1][1--100]的大小来决定整个变换的最小值, 这个有点像刷颜色的问题

/*
* SOLUTION 4:
* DP
* */
/**
* @param A: An integer array.
* @param target: An integer.
*/
public static int MinAdjustmentCost(ArrayList<Integer> A, int target) {
// write your code here
if (A == null || A.size() == 0) {
return 0;
}

// D[i][v]: 把index = i的值修改为v,所需要的最小花费
int[][] D = new int[A.size()][101];

int size = A.size();

for (int i = 0; i < size; i++) {
for (int j = 1; j <= 100; j++) {
D[i][j] = Integer.MAX_VALUE;
if (i == 0) {
// The first element.
D[i][j] = Math.abs(j - A.get(i));
} else {
for (int k = 1; k <= 100; k++) {
// 不符合条件
if (Math.abs(j - k) > target) {
continue;
}

int dif = Math.abs(j - A.get(i)) + D[i - 1][k];
D[i][j] = Math.min(D[i][j], dif);
}
}
}
}

int ret = Integer.MAX_VALUE;
for (int i = 1; i <= 100; i++) {
ret = Math.min(ret, D[size - 1][i]);
}

return ret;
}


刷墙的问题:对比起来真是一模一样

class Solution {
public:
/**
* @param costs n x 3 cost matrix
* @return an integer, the minimum cost to paint all houses
*/
int minCost(vector<vector<int>>& costs) {
// Write your code here
if (costs.size() == 0) //检查边界条件非常重要
return 0;

int n = costs.size();

vector<vector<int>> dp(n, vector<int>(3));

//dp[i][j] 表示计算到第i户时,他选择第j种颜色图墙时的最小价钱

for (int i=0; i<3; i++)
{
dp[0][i] = costs[0][i];
}

for (int i=1; i<n; i++)
{
for (int j=0; j<3; j++)
{
int minC = INT_MAX;
for (int k=0; k<3; k++)
{
if (k != j)
{
minC = min(minC, dp[i-1][k]);
}
dp[i][j] = minC + costs[i][j];
}
}
}

int minRet = INT_MAX;
for (int i=0; i<3; i++)
{
minRet = min(minRet, dp[n-1][i]);
}

return minRet;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: