【Lintcode】91 最小调整代价

目录

91. 最小调整代价

一、 原题

描述

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

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

样例

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

二、 求解

2.1 动态规划

思路:

构建一个n×101的dp二维数组, dp[i][j]表示 A[0~i] 中A[i]调整到 j 最小代价和, dp[i][j] 记录的是A中0 - i个元素中A[i] 调整到 j 时整体最小代价和;

  • 由此可以推出: dp[i][j] = dp[i - 1][k] + Math.abs( A[i] - j ), 由于k是变化的,j - target <= k <= j + target, 由此取dp[i-1][k] 的最小值 --> dp[i][j] 最小值
  • 初始化dp[0][j], 表示A[0] 调整到 j 时最小代价和, 由于只有一个数A[0], 因此dp[0][j] = Math.abs(A[0] - j)
  • 从上到下, 从左到右, 计算出dp[i][j]的值, 取dp[A.szie() - 1][j] 中最小的值 即为 最小的调整代价和;
public class Solution {
    /*
     * @param A: An integer array
     * @param target: An integer
     * @return: An integer
     */
    public int MinAdjustmentCost(List<Integer> A, int target) {
        // write your code here
        if(A == null) return -1;
        int len = A.size();
        int[][] dp = new int[len][101];
        
        for(int i = 0; i <= 100; i++){
            dp[0][i] = Math.abs(A.get(0) - i);
        }
        
        for(int i = 1; i < len; i ++){
            for(int j = 0; j < 101; j++){
                dp[i][j] = Integer.MAX_VALUE;
                int diff = Math.abs(A.get(i) - j);
                int start = (j - target < 0) ? 0 : j - target;
                int end = (j + target > 100) ? 100 : j + target;
                for(; start <= end; start++){
                    dp[i][j] = Math.min(dp[i-1][start] + diff, dp[i][j]);
                }
            }
        }
        int res = Integer.MAX_VALUE;
        for(int i = 0; i < 101; i++){
            res = Math.min(res, dp[len - 1][i]);
        }
        return res;
    }
}

猜你喜欢

转载自www.cnblogs.com/jxkun/p/9427971.html
91