最小调整代价【动态规划】

给一个整数数组,调整每个数的大小,使得相邻的两个数的差小于一个给定的整数target,调整每个数的代价为调整前后的差的绝对值,求调整代价之和最小是多少。

样例
对于数组[1, 4, 2, 3]和target=1,最小的调整方案是调整为[2, 3, 2, 3],调整代价之和是2。返回2。

注意
你可以假设数组中每个整数都是正整数,且小于等于100。
————————————————

【思路】

因为数的范围是1~100,每个数有100中调整的可能性,采用动态规划的思路。

建立大小为(n+1)*101的二维数组rec记录所有可能调整的代价,第一行初始化为全0,其他行为最大值。

rec中第i行对应A[i-1]。对于每个数A[i],调整后的结果有100种,用rec[i][j]表示数字A[i]调整为j的最小代价。对于每个rec[i][j],A[i-1]调整到k的代价加上A[i]调整到j的最小代价即为rec[i][j]的代价。而k又有100种选择,对于j,当|j-k|的绝对值不大于target时,代价最小,当前rec[i][j]为rec[i-1][k] +( j - A[i-1]),rec[i][j]保留所有可能代价中的最小代价。

最后,rec[n][0~100]中的最小代价即为对整个数组调整后的最下代价。
————————————————
 

class Solution {
public:
    /**
     * @param A: An integer array.
     * @param target: An integer.
     */
    int MinAdjustmentCost(vector<int> A, int target) {
        // write your code here
        
        int n = A.size();
        vector<vector<int> > rec(n+1, vector<int> (101, numeric_limits<int>::max()));
        //初始化第一行为0
        //rec[i][j]表示第i个数调整到j的最小代价,k表示相邻两个数调整到某个值的所有可能
        rec[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++) {
                    //如果k在target范围内,更新rec[i][j]的值为上一个数到k的代价,加上当前数到j的代价
                    if (abs(j-k) <= target)
                        rec[i][j] = min(rec[i-1][k] + abs(A[i-1]-j), rec[i][j]);
                }
            }
        }
        int cost = numeric_limits<int>::max();
        for (int i = 0; i <= 100; ++i) {
            cost = min(cost, rec[n][i]);
        }
        return cost;
    }
};
class Solution {
public:
    /

    **
* @ param
A: An
integer
array.
* @ param
target: An
integer.
* /
int
MinAdjustmentCost(vector < int > A, int
target) {
        // write
your
code
here
int
n = A.size();
if (n < 2)
{
return 0;
}

int
buf[n][101];
for (int i = 1; i <= 100; i++)
{
buf[0][i] = abs(i - A[0]);
}

for (int i = 1; i < n; i++)
{
    for (int j = 1; j <= 100; j++)
        {
            int
        left = max(j - target, 1);
        int
        right = min(j + target, 100);
        buf[i][j] = INT_MAX;
        for (int k = left; k <= right; k++)
        {
            buf[i][j] = min(buf[i][j], buf[i-1][k]+abs(A[i]-j));
        }
        }
}

int
result = INT_MAX;
for (int i = 1; i <= 100; i++)
{
result = min(result, buf[n - 1][i]);
}

return result;
}
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值