动态规划(1)
1.basic skills:递归+暴力搜索
2.动态规划Dynamic Programming(DP)
(1)本质:递归。递归不能解决的问题动态规划也不能解决。
(2)原问题(N)- >子问题->原问题(N)。把原问题拆解成子问题,在得到子问题的答案之后再得到原问题的答案。递归关注的是解决问题的方式,怎么把很复杂的问题拆解成一层一层的,递归的时间复杂度是多少等写完之后再说。
(3)最优子结构:子问题的最优决策可以导出原问题的最优决策
(4)无后效性。
(5)重叠子问题:去冗余,空间换时间。
3.target:分析-->coding->ac
4.leetcode实训
(198抢劫)代码:
去冗余之前
package com.nowcoder.leetcode; public class HouseRobber_198 { //递归的方式,idx代表已经抢到的位置, public static int solve1(int idx,int[] nums){ //越界就返回 if(idx<0){ return 0; } return Math.max(nums[idx]+solve1(idx-2,nums),solve1(idx-1,nums)); } //第一种方法暴力递归 public static int rob(int[] nums){ return solve1(nums.length,nums); } }
去冗余之后
class Solution { public static int[] res; public int solve(int idx,int[] nums){ if(idx<0){ return 0; } if(res[idx]>=0){ return res[idx]; } res[idx]=Math.max(nums[idx]+solve(idx-2,nums),solve(idx-1,nums)); return res[idx]; } public int rob(int[] nums){ res=new int[nums.length]; for(int i = 0 ; i<nums.length;++i){ res[i]=-1; } return solve(nums.length-1,nums); } }
5.共性问题:
(1)套路:最优,最大,最小,最长,计数
(2)离散问题:容易设计状态(整数的01背包问题)
(3)最优子结构:N-1可以推导出N
6.基本步骤:四个步骤
(1)涉及暴力算法,找到冗余
(2)设计并存储堆的状态(一维、二维、三维数组甚至是用Map)
(3)递归式(状态转移方程):递归中有两个值组成,每个值代表一种决策,每个决策里面都有一个递归。
(4)自底向上计算最优解(编程方式):先计算比较大的,然后计算比较小的,但是自顶向下代码量比较大的。自底向上是先计算比较小的,