lintcode练习 - 91. 最小调整代价

版权声明:原创部分都是自己总结的,如果转载请指明出处。觉得有帮助的老铁,请双击666! https://blog.csdn.net/qq_36387683/article/details/82558893

91. 最小调整代价

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

样例

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

注意事项

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

解题思路:

动态规划的题。

数组中的数值上限是upper_limit 是数组中的最大值max(num) + target,即使数值怎么调整,也只会在0-upper_limit间变动。

所以我们定义动态规划数组dp , shape(n+1, upper_limit+1),dp[i][j]表示调整到第i个数时,第i个数取值为J的最小代价和。

dp[0]没有任何数组,所以全部为0

动态规划的方程为:

dp[i][j] = min(dp[i-1][left:right +1]) + abs(nums[i-1] - j)

abs(nums[i-1] - j) 表示第i个数调整到j自身的代价,min(dp[i-1][left:right +1]) + abs(nums[i-1] - j)是前一个数累计的最小代价。

其中left是能够调整到J的最小范围,right是能够调整到J的最大范围。

扫描二维码关注公众号,回复: 3538045 查看本文章
class Solution:
    """
    @param: A: An integer array
    @param: target: An integer
    @return: An integer
    """
    def MinAdjustmentCost(self, A, target):

        n = len(A)
        #最大的数值界限
        upper_limit = max(A) + target
        
        #定义二维数组,shape=(n+1,upper_limit)数的个数,数值的范围
        dp = [[0] * (upper_limit + 1) for _ in range(n + 1)]
        
        for i in range(1, n + 1):
            for j in range(upper_limit + 1):
                #left = 如果小于0就取0,否者取j - target; right = 如果大于upper_limit就取upper_limit,否则就取j+target
                #left和right就是J能够调整的数值范围
                left, right = max(0, j - target), min(upper_limit, j + target)
                
                #dp[i][j]表示调整到第i个数时,第i个数取值为J的最小代价和
                #abs(a[i-1] - j)是第i个数调整到J自身需要的代价
                dp[i][j] = min(dp[i - 1][left:right + 1]) + abs(A[i - 1] - j)
        
        return min(dp[n])

 

猜你喜欢

转载自blog.csdn.net/qq_36387683/article/details/82558893