91-最小调整代价
给一个整数数组,调整每个数的大小,使得相邻的两个数的差不大于一个给定的整数target,调整每个数的代价为调整前后的差的绝对值,求调整代价之和最小是多少。
注意事项
你可以假设数组中每个整数都是正整数,且小于等于100。
样例
对于数组[1, 4, 2, 3]和target=1,最小的调整方案是调整为[2, 3, 2, 3],调整代价之和是2。返回2。
标签
动态规划 背包问题 LintCode 版权所有
思路
参考博客:http://blog.csdn.net/sinat_26230689/article/details/51873612
因为数的范围是1~100,每个数有100中调整的可能性,采用动态规划的思路。
建立大小为(n+1)*101的二维数组rec记录所有可能调整的代价,第一行初始化为全0,其他行为最大值。
dp中第i行对应A[i-1]。对于每个数A[i],调整后的结果有100种,用dp[i][j]表示数字A[i]调整为j的最小代价。对于每个dp[i][j],A[i-1]调整到k的代价加上A[i]调整到j的最小代价即为dp[i][j]的代价。而k又有100种选择,对于j,当|j-k|的绝对值不大于target时,代价最小,当前dp[i][j]为dp[i-1][k] +( j - A[i-1]),dp[i][j]保留所有可能代价中的最小代价。
最后,dp[n][0~100]中的最小代价即为对整个数组调整后的最下代价。
code
class Solution {
public:
/**
* @param A: An integer array.
* @param target: An integer.
*/
int MinAdjustmentCost(vector<int> A, int target) {
// write your code here
int size = A.size(), i = 0, j = 0, k = 0;
if(size <= 0) {
return 0;
}
vector<vector<int> > dp(size+1, vector<int> (101, 0x7FFFFFFF));
dp[0] = vector<int>(101, 0);
for(i=1; i<=size; i++) {
for(j=0; j<=100; j++) {
for(k=0; k<=100; k++) {
if (abs(j - k) <= target) {
dp[i][j] = (dp[i-1][k]+abs(A[i-1]-j)) > dp[i][j] ? dp[i][j] : (dp[i-1][k]+abs(A[i-1]-j));
}
}
}
}
int minCost = 0x7FFFFFFF;
for(i=0; i<=100; i++) {
minCost = minCost > dp[size][i] ? dp[size][i] : minCost;
}
return minCost;
}
};