动态规划--最小调整代价

91. Minimum Adjustment Cost

【题目】

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]|

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

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

【例子】

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

【思路】

因为数的范围是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;
    }
};

为什么不能使用一维数组记录最小代价并更新?

因为与背包问题不同,背包问题中的每个物品可以只根据前面的物品放置状况调整,可以用一维数组记录上一个物品调整后的状态,对于当前物品从后往前进行操作,保证使用的都是上一个物品调整后的状态。但本题中,每个位置的数与它前后相邻的数都有关,使用一维数组只能保证左边为之前的状态,右边为当前物品的状态,无法用右边的数进行更新。

    原文作者:动态规划
    原文地址: https://blog.csdn.net/sinat_26230689/article/details/51873612
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞