动态规划讲解
整理自牛客网左程云视频课程
目录
例子:
1. 暴力搜索方法
暴力递归会有很多重复计算。
2. 记忆搜索方法
记忆搜索方法算是一种动态规划方法。
3. 动态规划方法
第一列的值都为0,第一行中 aim 值为 arr[0] 整数倍的位置的值是1,其余位置是0。
dp[i][j]的值为以上值的累加,从左到右,从上到下依次填表,最右下角的值即为所求。
求每一个位置都需要枚举,时间复杂度为O(aim),dp 一种有N*aim 个位置,所以总时间复杂度为 O(N *aim^2)。
4.记忆搜索方法与动态规划方法的联系
5.什么是动态规划
因为规定了计算顺序,所以可以利用以前的结果进行优化,去掉枚举过程。
经过化简后时间复杂度为 O(N*aim)。
6.总结
暴力递归题目可以优化成动态规划方法的大体过程:
动态规划方法的关键点:
7.例题
7.1 走完台阶有多少种方法
有 n 级台阶,一个人每次上一级或两级,问有多少种走完 n 级台阶的方法?
递推式:
暴力递归方法:
动态规划:
public int s1(int n){
if(n < 1){
return 0;
}
if(n == 1 || n == 2){
return n;
}
int pre = 2;
int prePre = 1;
int result = 0;
for(int i = 3;i <= n;i++){
result = pre + prePre;
pre = result;
prePre = pre;
}
return result;
}
7.2 矩阵中最小路径和
解法:
从左到右,从上到下计算每个位置的值,最后右下角的值即为所求。
7.3 数组最长递增子序列长度
解法:
求 dp[2] 的值:找 arr[2] 左边比它小的数, 哪个 dp 值最大,将其作为倒数第二个数。
所以状态方程为:
如果左边没有比 arr[i] 小的数,那么 dp[i]=1。
7.4 两个字符串的最长公共子序列
解法:
7.5 背包问题
解法:
7.6 将 str1 编辑成 str2 的最小代价
解法:
以上四种可能的值中,选最小值作为 dp[i][j] 的值。
最终结果返回 dp 最右下角的值。
附:
另一篇关于动态规划不错的博客 https://blog.csdn.net/u013309870/article/details/75193592