动态规划解题步骤
1.定义子问题:
什么可以算得上有子问题,可以用动态规划解决的问题呢?例如在打家劫舍的算法题中,问题可以被拆分为各个子问题,子问题是打劫前k家能得到的最大金额。假设一共有 n 个房子的话,就一共有 n个子问题。动态规划实际上就是通过求这一堆子问题的解,来求出原问题的解。这要求子问题需要具备两个性质:
(1)原问题要能由子问题表示。例如这道小偷问题中,k=n 时实际上就是原问题。否则,解了半天子问题还是解不出原问题,那子问题岂不是白解了。
(2)一个子问题的解要能通过其他子问题的解求出。例如这道小偷问题中,f(k)可以由 f(k-1)和 f(k-2) 求出。这个性质就是教科书中所说的“最优子结构”。如果定义不出这样的子问题,那么这道题实际上没法用动态规划解。
2.写子问题的递推关系:
子问题之间存在一种递推关系。第k个子问题的结果是由第k-1或者k-2个子问题的结果得出的。
3.确定DP数组的计算顺序:
DP 数组也可以叫”子问题数组”,因为 DP 数组中的每一个元素都对应一个子问题。dp[k] 对应子问题 f(k),即偷前 k 间房子的最大金额。
4.空间优化
案例:(leetcode198)
代码:
class Solution {
public int rob(int[] nums) {
int len = nums.length;
int[] max = new int[len];
if(len == 0){
return 0;
}
if(len ==1){
return nums[0];
}
max[0] = nums[0];
for(int i=1;i<len;i++){
max[i] = Math.max(max[i-1],(nums[i]+((i-2<0) ? 0:max[i-2]))) ;
}
return max[len-1];
}
}