LintCode:91.最小调整代价(动态规划)

题目:


分析:本题类似于一个背包问题,数组中的元素一个个调整,由于是求相邻元素的差值,所以只和前一个相邻元素的值有关,所以只需要记录上一个调整的值就可以。

dp[i][j]表示调整到第i个数时,此时,第i个数取值为j,为代价和最小。

显然dp[i-1][k]已知,则调整的总代价为dp[i][j]=dp[i-1][k]+abs(j-A[i])

由于j和k有多种取值可能,所以循环求解判断,k表示前一个数,j表示现在的数,假设j确定,那么k的取值就是在一个范围内,因为差值不能超过target。

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
        int[][] dp=new int[A.size()+1][101];
        //dp[i][j]表示数字A[i]调整到j的最小代价,dp[i][j]为数字A[i-1]调整到k的最小代价加上A[i]调整到j之和。k的取值有100种,应挑选与j之差绝对值不大于target的,代价最小
        for(int i=1;i<=A.size();i++){
            for(int j=0;j<=100;j++){
                dp[i][j]=Integer.MAX_VALUE;
            }
        }
        for(int i=1;i<=A.size();i++){
            for(int j=0;j<=100;j++){
                int left=Math.max(1,j-target);  //k可调整到的最小值
                int right=Math.min(100,j+target);  //k可调整到的最大值
                for(int k=left;k<=right;k++) {
                    dp[i][j] = Math.min(dp[i][j], dp[i - 1][k] + Math.abs(A.get(i-1) - j)); //此时A[i]移动到j的位置,cost为abs(A.get(i)-j)
                }
            }
        }
        int mincost=Integer.MAX_VALUE;
        for(int i=0;i<=100;i++){
            if(mincost>dp[A.size()][i]){
                mincost=dp[A.size()][i];
            }
        }
        return mincost;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_27139155/article/details/80492174