动态规划常见题型--最小调整代价(Java)

最小调整代价

动态规划本质上是记录在程序运行过程中产生的数据以达到优化时间复杂度的目的,较为经典的有背包问题的解决:

https://blog.csdn.net/qq_34861102/article/details/79903634

这里记录一下认为常见的题型


使用二维数组:

http://www.lintcode.com/zh-cn/problem/minimum-adjustment-cost/

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

这一看就是一个需要用动态规划解决的问题

步骤:

使用一个二维数组dp记录调整的代价(length * 101
其中dp[i][j]表示第i个数调整为j的最小代价
因此只需要查看一下dp[i][j]是怎么推导出来的即可
dp[i][j]的取值从 dp[i-1][k]+abs(A[i-1]-j) 和其本身中的最小值选取(这里的kj是一个循环,从1到100,表示每种情况都会考虑到,这样就可以)
dp[i-1][k]+abs(A[i-1]-j)表示的含义即第i - 1个数变成到k的最小代价加上第i个数(A[i-1]0 开始的)到 j 的代价
这样最后就能得到 100 个最小代价的值

重点:按照这个思路进行,但是中间忘记考虑了kj的关系,仅当两者的绝对值小于 target 的时候才可以进行转换

代码如下:

public class Solution {
    /*
     * @param A: An integer array
     * @param target: An integer
     * @return: An integer
     */
    public int MinAdjustmentCost(List A, int target) {
        // write your code here
        int[][] dp = new int[A.size()+1][101];
        for (int i = 0; i < 101; i ++){
            dp[0][i] = 0;
        }
        for (int k = 1; k <= A.size();k ++){
            for (int i = 0; i < 101; i ++){
                dp[k][i] = Integer.MAX_VALUE;
            }
        }
        for (int i = 1; i <= A.size(); i ++){
            for (int j = 0; j <= 100; j ++){
                for (int k = 0; k < 100; k ++){
                    if ( Math.abs(j - k) <= target ){
                        dp[i][j] = Math.min(dp[i][j],dp[i-1][k]+Math.abs(A.get(i-1)-j));
                    }
                }
            }
        }
        int ans = dp[A.size()][0];
        for (int i = 1; i < 100; i++){
            ans = Math.min(ans,dp[A.size()][i]);
        }
        return ans;
    }
}

你可能感兴趣的:(常见算法)