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