序列DP leetcode 674 最长连续递增序列 原题链接:https://leetcode.cn/problems/longest-continuous-increasing-subsequence/description/ 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class  Solution  {    public  int  findLengthOfLCIS (int [] nums)  {         int  n  =  nums.length;         int  [] f = new  int  [n];         Arrays.fill(f,1 );         int  ans  =  1 ;         for (int  i  =  1  ; i < n ; i++){             if (nums[i] > nums[i -1 ] ){                 f[i] = Math.max(f[i],f[i - 1 ] + 1 );             }             ans = Math.max(ans,f[i]);         }         return  ans;     } } 
 
leetcode 62 不同路径 原题链接:https://leetcode.cn/problems/unique-paths/ 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class  Solution  {    public  int  uniquePaths (int  m, int  n)  {         int  [][] f = new  int  [m + 1 ][n + 1 ];                  f[1 ][1 ] = 1 ;         for (int  i  =  1 ; i <= m; i++){             for (int  j  =  1  ; j <= n ; j++){                                  f[i][j] += f[i - 1 ][j] + f[i][j - 1 ]  ;             }            }         return  f[m][n];     } } 
 
leetcode 70 爬楼梯 原题链接:https://leetcode.cn/problems/climbing-stairs/description/ 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26   class  Solution  {    public  int  climbStairs (int  n)  {         if (n == 1 ){             return  1 ;         }         if (n == 2 ){             return  2 ;         }         int  []  f = new  int  [n + 1 ];         f[1 ] = 1 ;         f[2 ] = 2 ;         for (int  i  =  3  ; i <= n ; i++){             f[i] = f[i - 1 ] + f[i - 2 ];         }         return  f[n];     } } 
 
leetcode 64 最小路径和 原题链接:https://leetcode.cn/problems/minimum-path-sum/description/ 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class  Solution  {    public  int  minPathSum (int [][] grid)  {         int  m  =  grid.length;         int  n  =  grid[0 ].length;         int  [][] f = new  int  [m][n];         for (int  i  =  0  ; i < m; i++){                for (int  j  =  0 ; j < n ; j++){                 if (i == 0  && j == 0 ){                     f[i][j] = grid[i][j];                 }else  if (i == 0 ){                     f[i][j] = f[i][j - 1 ] + grid[i][j];                 }else  if (j == 0 ){                     f[i][j] = f[i - 1 ][j] + grid[i][j];                  }else {                     f[i][j] = Math.min(f[i - 1 ][j],f[i][j - 1 ]) + grid[i][j];                 }             }         }         return  f[m - 1 ][n - 1 ];     } } 
 
leetcode 368 最大整除子集 原题链接:https://leetcode.cn/problems/largest-divisible-subset/description/ 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 class  Solution  {    public  List<Integer> largestDivisibleSubset (int [] nums)  {                                    Arrays.sort(nums);         int  n  =  nums.length;                  int  [] f = new  int  [n];                  int  [] g = new  int  [n];         for (int  i  =  0  ; i < n ; i++){             int  prev  =  i;             int  len  =  1 ;             for (int  j  =  0  ; j < n ; j++){                 if (nums[i] % nums[j] == 0  ){                     if (len < f[j] + 1 ){                         len = f[j] + 1 ;                         prev = j;                     }                 }             }             f[i] = len;             g[i] = prev;          }         int  idx  =  -1 ;         int  max  =  -1 ;         for (int  i  =  0  ; i < n; i++){             if (f[i] > max){                 max = f[i];                 idx = i;             }         }         List<Integer> ans = new  ArrayList <>();         while (ans.size() < max){             ans.add(nums[idx]);             idx = g[idx];         }         return  ans;     } } 
 
leetcode 300 最长递增子序列 原题链接:https://leetcode.cn/problems/longest-increasing-subsequence/description/ 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class  Solution  {    public  int  lengthOfLIS (int [] nums)  {         int  n  =  nums.length;         int  [] f = new  int  [n + 1 ];         int  ans  =  1 ;         for (int  i  =  0  ; i < n ; i++){             f[i] = 1 ;             for (int  j  =  0  ; j < i ; j++){                 if (nums[i] > nums[j]){                     f[i] = Math.max(f[i], f[j] + 1 );                     ans = Math.max(ans,f[i]);                 }                 }         }         return  ans;     } } 
 
53 最大子数组和 原题链接:https://leetcode.cn/problems/maximum-subarray/?envType=daily-question&envId=2023-11-20 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class  Solution  {    public  int  maxSubArray (int [] nums)  {         int  n  =  nums.length;         int  [] f = new  int  [n];         f[0 ] = nums[0 ];         int  ans  =  f[0 ];         for (int  i  =  1 ; i < n; i++){             f[i] = Math.max(nums[i],f[i - 1 ] + nums[i]);             ans = Math.max(ans,f[i]);         }         return  ans;     } } 
 
股票问题 leetcode 121. 买卖股票的最佳时机 这题可以用DP做 但不是最优解 最优解是枚举 只要有 后面的最大减前面最小的组合一组成立即可 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class  Solution  {    public  int  maxProfit (int [] prices)  {         int  n  =  prices.length;         int  [][] f = new  int  [n][2 ];         f[0 ][0 ] = 0 ;         f[0 ][1 ] = -prices[0 ];         for (int  i  =  1  ; i < n ; i++){             f[i][0 ] = Math.max(f[i - 1 ][0 ],f[i - 1 ][1 ] + prices[i]);                          f[i][1 ] = Math.max(f[i - 1 ][1 ],-prices[i]) ;         }         return  Math.max(f[n - 1 ][0 ],f[n - 1 ][1 ]);     } } 
 
最优解 枚举 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class  Solution  {    public  int  maxProfit (int [] prices)  {         int  min  =  Integer.MAX_VALUE;         int  n  =  prices.length;         int  ans  =  0 ;         for (int  i  =  0  ; i < n ;i++){             if (prices[i] < min){                 min = prices[i];             }             ans = Math.max(ans,prices[i] - min);         }                  return  ans;     } } 
 
leetcode 122. 买卖股票的最佳时机 II 原题链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/ 
用贪心做会更快一些  但dp也行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class  Solution  {    public  int  maxProfit (int [] prices)  {         int  n  =  prices.length;         int  [][] f = new  int  [n][2 ];         f[0 ][0 ] = 0 ;         f[0 ][1 ] = -prices[0 ];         for (int  i  =  1  ; i < n;i++){             f[i][0 ] = Math.max(f[i - 1 ][0 ],f[i - 1 ][1 ] + prices[i]);             f[i][1 ] = Math.max(f[i - 1 ][1 ],f[i - 1 ][0 ] - prices[i]);         }         return  Math.max(f[n - 1 ][0 ],f[n - 1 ][1 ]);     } } 
 
贪心解法
1 2 3 4 5 6 7 8 9 10 11 12 class  Solution  {    public  int  maxProfit (int [] prices)  {         int  res  =  0 ;         int  n  =  prices.length;         for (int  i  =  1  ; i < n ; i++){             res += Math.max(0 ,prices[i] - prices[i - 1 ]);         }         return  res;     } } 
 
线性DP leetcode 97. 交错字符串 原题链接:https://leetcode.cn/problems/interleaving-string/ 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class  Solution  {    char  [] cs(String s){         return  s.toCharArray();     }     public  boolean  isInterleave (String s1, String s2, String s3)  {         int  n  =  s1.length(), m = s2.length();         if (n + m != s3.length()){             return  false ;         }         boolean  [][] f = new  boolean  [n + 1 ][m + 1 ];                  f[0 ][0 ] = true ;         var  cs1  =  cs(s1);         var  cs2  =  cs(s2);          var  cs3  =  cs(s3);                           for (int  i  =  1  ; i <= n && f[i - 1 ][0 ] ; i++ ){             f[i][0 ] = cs1[i - 1 ] == cs3[i - 1 ];         }         for (int  i  =  1 ; i <= m && f[0 ][i - 1 ]; i++){             f[0 ][i] = cs2[i - 1 ] == cs3[i - 1 ];         }         for (int  i  =  1  ; i <= n ; i++){             for (int  j  =  1  ; j <= m ; j++ ){                   if (cs1[i - 1 ] == cs3[i + j - 1 ]){                     f[i][j] |= f[i - 1 ][j];                 }                 if (cs2[j - 1 ] == cs3[i + j - 1 ]){                     f[i][j] |= f[i][j - 1 ];                 }             }         }         return  f[n][m];     } } 
 
跳跃游戏 leetcode 55. 跳跃游戏 原题链接:https://leetcode.cn/problems/jump-game/ 
这题动态规划可以做 但不是最优解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class  Solution  {    public  boolean  canJump (int [] nums)  {         int  n  =  nums.length;         if (n <=  1 ){             return  true ;         }                  if (nums[0 ] == 0 ){             return  false ;         }         int  [] f = new  int  [n];         f[0 ] = nums[0 ];          for (int  i  =  1  ; i < n ; i++){              f[i] = Math.max(f[i - 1 ],nums[i] + i);                            if (f[i] >= n - 1 ){                  return  true ;              }                            if (f[i] == i){                 return  false ;              }          }          return  true ;     } } 
 
一次遍历的解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class  Solution  {    public  boolean  canJump (int [] nums)  {         int  n  =  nums.length;         int  k  =  0 ;         for (int  i  =  0  ; i < n ; i++){             if (i > k){                 return  false ;             }             k = Math.max(k,i + nums[i]);         }         return  true ;     } } 
 
leetcode 45. 跳跃游戏 II 原题链接:https://leetcode.cn/problems/jump-game-ii/description/ 
DP可以做 但不是最优解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class  Solution  {    public  int  jump (int [] nums)  {         int  n  =  nums.length;             if (n <= 1 ){             return  0 ;         }         int  [] f = new  int  [n];         Arrays.fill(f,Integer.MAX_VALUE);         f[0 ] = 0 ;         for (int  i  =  1  ; i < n; i++){             for (int  j  =  0  ; j < i ; j++){                                  if (nums[j] >= i - j){                     f[i] = Math.min(f[j] + 1 ,f[i]);                 }             }         }                  return  f[n - 1 ];     } } 
 
最优解 贪心
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class  Solution  {    public  int  jump (int [] nums)  {         int  n  =  nums.length;         if (n <= 1 ){             return  0 ;         }                  int  next  =  0 ;         int  end  =  0 ;                  int  ans  =  0 ;                                    for (int  i  =  0  ; i < n - 1  ; i++){             next = Math.max(next,i + nums[i]);                          if (end ==  i){                 end =  next;                 ans++;             }           }         return  ans;     } } 
 
树形DP acwing 285. 没有上司的舞会 原题链接:https://www.acwing.com/problem/content/287/ 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 import  java.util.Arrays;import  java.util.Scanner;public  class  Main  {    public  static  final  int  N  =  6010 ;          public  static  int  [] e, h, ne, happy;     public  static  boolean  [] has_father;     public  static  int  [][] f;     public  static  int  idx;     public  static  void  main (String[] args)  {         e = new  int [N];         ne = new  int [N];         h = new  int [N];         happy = new  int  [N];         has_father = new  boolean [N];                  Arrays.fill(h,-1 );         idx = 0 ;         Scanner  sc  =  new  Scanner (System.in);         int  n  =  sc.nextInt();                                    for (int  i  =  1  ; i <= n ; i++){             happy[i] = sc.nextInt();         }         for  (int  i  =  0  ; i < n - 1  ; i++){                          int  a,b;             a = sc.nextInt();             b = sc.nextInt();                          has_father[a] = true ;             add(b,a);         }         f = new  int [N][2 ];         int  root  =  1 ;         while  (has_father[root]){             root++;         }         dfs(root);         System.out.println(Math.max(f[root][0 ],f[root][1 ]));     }     public  static  void  dfs (int  u) {                  f[u][1 ] = happy[u];         for  (int  i  =  h[u]; i != -1 ; i = ne[i]){             int  j  =  e[i];                          dfs(j);                                       f[u][0 ] += Math.max(f[j][0 ],f[j][1 ]);                          f[u][1 ] += f[j][0 ];         }     }     public  static  void  add (int  a,int  b) {         e[idx] = b;         ne[idx] = h[a];         h[a] = idx++;     } }