java-动态规划学习笔记

104 阅读2分钟

java-动态规划学习笔记

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

动态规划定义:

将一个问题分解为若干个子问题,对每个子问题求最优解,前一个子问题的最优解,为下面子问题提供了有效信息,依次解决子问题,最后一个子问题就是初始问题的最优解。

动态规划应用于子问题重叠情况,子问题的划分是通过递归实现的,为了避免子问题的重复计算,每个子问题只求解依次,将会保存在数组中。

注意: 它与分治相似,都是通过组合子问题解决原问题,但是与分治不同在于:分治法的子问题是相互独立存在的,而动态规划应用于子问题的重叠情况。

基本步骤:

1、刻画一个最优解的结构特征

2、递归地定义最优解的值

3、计算最优解的值,通常采用自底向上的方法

4、利用算出的信息构造出一个最优解

什么时候使用:

动态规划的问题有两个特征(1)最优子结构。如果一个问题的最优解包含子问题的最优解,那么该问题具有最优子结构;(2)重叠子问题。如果递归反复计算相同的子问题,那么该问题具有重叠子问题。如果在递归的每一步都生成新的子问题,那么就要使用分治法解决。

示例

最长公共子串、0-1背包问题、钢条切割问题

举例:最长公共子串

public class Solution {
    public String LCS (String str1, String str2) {
    if(str1 == null || str2 == null){
            return null;
        }
        
        int m = str1.length();
        int n = str2.length();
        
        int[][] dp = new int [m+1][n+1];
        
        int max = 0, end = 0;
        
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
               if(str1.charAt(i) == str2.charAt(j)){
                    dp[i+1][j+1] = dp[i][j]+1;
                    
                   if(max <  dp[i+1][j+1]){
                       max =  dp[i+1][j+1];
                       end = i;
                   }
               }else{
                    dp[i+1][j+1] = 0;
               } 
            }
        }
        
        return max ==0 ? "-1":str1.substring(end - max +1, end+1);
    }
}