给一个整数数组,调整每个数的大小,使得相邻的两个数的差不大于一个给定的整数target,调整每个数的代价为调整前后的差的绝对值,求调整代价之和最小是多少。
你可以假设数组中每个整数都是正整数,且小于等于100。
您在真实的面试中是否遇到过这个题?
是
样例
对于数组[1, 4, 2, 3]和target=1,最小的调整方案是调整为[2, 3, 2, 3],调整代价之和是2。返回2。
class Solution {
public:
/*
* @param A: An integer array
* @param target: An integer
* @return: An integer
*/
int MinAdjustmentCost(vector<int> &A, int target) {
// write your code here
// return MinAdjustmentCostDP(A, target);
// save history to avoid duplicate computing
vector<vector<int>> dp(A.size(), vector<int>(101, -1));
return MinAdjustmentCostDFS(A, dp, target, 0, -1);
}
int MinAdjustmentCostDP(vector<int> &A, int target) {
int n = A.size();
if (n == 0) {
return 0;
}
// adjust size max = 100 + k; min = -k; include 0
vector<vector<int>> dp(n + 1, vector<int>(101, INT_MAX));
// init
dp[0] = vector<int>(101, 0);
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= 100; j++) {
for (int k = 0; k <= 100; k++) {
if (abs(j - k) <= target) {
dp[i][j] = min(dp[i - 1][k] + abs(j - A[i - 1]), dp[i][j]);
}
}
}
}
int minadjust = INT_MAX;
for (int j = 0; j <= 100; j++) {
if (minadjust > dp[n][j]) {
minadjust = dp[n][j];
}
}
return minadjust;
}
int MinAdjustmentCostDFS(vector<int> &A, vector<vector<int>> &dp, int target, int sub, int lastvalue) {
if (sub == A.size()) {
return 0;
}
if (lastvalue >= 0 && dp[sub][lastvalue] != -1) {
return dp[sub][lastvalue];
}
int end = lastvalue < 0 ? 100 : min(lastvalue + target, 100);
int start = lastvalue < 0 ? 0 : max(lastvalue - target, 0);
int minadjust = INT_MAX;
for (int i = start; i <= end; i++) {
minadjust = min(abs(A[sub] - i) + MinAdjustmentCostDFS(A, dp, target, sub + 1, i), minadjust);
}
if (lastvalue >= 0) {
dp[sub][lastvalue] = minadjust;
}
return minadjust;
}
};