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);
}
}