最小调整代价
动态规划本质上是记录在程序运行过程中产生的数据以达到优化时间复杂度的目的,较为经典的有背包问题的解决:
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)
和其本身中的最小值选取(这里的k
和j
是一个循环,从1到100
,表示每种情况都会考虑到,这样就可以)
dp[i-1][k]+abs(A[i-1]-j)
表示的含义即第i - 1
个数变成到k
的最小代价加上第i
个数(A[i-1]
从 0
开始的)到 j
的代价
这样最后就能得到 100
个最小代价的值
重点:按照这个思路进行,但是中间忘记考虑了k
和j
的关系,仅当两者的绝对值小于 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];
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;
}
}