• 【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;
        }
    }
    
  • 相关阅读:
    剑指offer--50.滑动窗口的最大值
    剑指offer--49.矩阵中的路径
    剑指offer--48.机器人的运动范围
    剑指offer--47.数据流中的中位数
    剑指offer--46.字符流中第一个不重复的字符
    剑指offer--45.二叉树的深度
    剑指offer--44.两个链表的第一个公共结点
    剑指offer--43.连续子数组的最大和
    海盗分宝石问题
    C++数组名退化指针实例
  • 原文地址:https://www.cnblogs.com/jxkun/p/9427971.html
Copyright © 2020-2023  润新知