算法之动态规划

算法之动态规划

  • 什么是动态规划
  • 为什么要用动态规划
  • 如何利用动态规划解决问题
    • 1.斐波那契数列
    • 2.连续子数组的最大和

什么是动态规划

  • 什么是动态规划?
    动态规划 dynamic programming 简称DP。其基本思想是:将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后从这些子问题的解得到原问题的解;对于重复出现的子问题,只在第一次遇到的时候对它进行求解,并把答案保存起来,让以后再次遇到时直接引用答案,不必重新求解。动态规划算法将问题的解决方案视为一系列决策的结果。

  • 动态规划的步骤
    1.确定状态
    2.定义状态转移方程
    3.求得最优解

为什么要用动态规划

提到动态规划,我们就不得不和优化相关联起来,动态规划本质也是利用空间来换时间的思想,先将子问题存储起来,后面求解较大规模的问题的时候可以直接利用子规模问题的解。这样就节省了重复计算的时间,同时也可将复杂的问题转化为一个个简单的小问题。

如何利用动态规划解决问题

下面给出几个案例来分析如何使用动态规划

1.斐波那契数列

算法之动态规划_第1张图片
这题的解决方案有很多,有递归,迭代相加,动态规划,这里主要分析动态规划如何解决此问题。

1.确定DP状态
根据斐波那契函数,我们可以看出第一项和第二项的值恒为1,后面每一项都是前两项的和。因此我们定义一个dp数组来存储每一次前两项运算所得的值,也就是每个子状态的值。可以这么定义:int[] dp。默认前两项目是固定的值,所以dp[1]=1,dp[2]=1;

2.定义状态转移方程

根据函数方程我们很明显得能确定状态转移方程是 下一次的值等于前两次值之和,dp[i]=d[i-1]+dp[i-2]

3.求得最优解
根据状态转移方程,我们即可写出算法的全过程,并求得dp[n]的值,下面给出动态规划算法的java代码:

public class Solution {
    public int Fibonacci(int n) {
        //1和2是常数函数,直接返回
        if(n<3) return 1;
        int[] dp = new int[n+1];
        //先规定好前两项
        dp[1]=dp[2]=1;
        //利用动态规划,逐个求出后面的值
        for(int i=3;i<=n;i++){
            dp[i] = dp[i-1]+dp[i-2];
        }
        return dp[n];
    }
}

2.连续子数组的最大和

算法之动态规划_第2张图片
1.确定DP状态
此题没有给出函数方程,但是从题干中,我们不难可以推断出,用一个dp数组来存放第 i 个连续子数组的最大值,因为我们可以将i从0到n逐个遍历,利用状态转移方程,我们即可比较出在 i 位置上的最大值,并存放到dp[i]的位置。

2.定义状态转移方程
我们可以将dp[i]存储为第i个连续子数组的最大值,那么如何确定这个最大值呢?这时候我们就需要状态转移方程,同样我们需要利用上一个子问题的解,来求得下一个状态的解,假设输入的输入定义为int[] arr那么我们可以定义状态转移方程为dp[i] = max(dp[i],dp[i-1]+arr[i]),这样我们就可以求得dp[i]位置的最大值到底是 (dp[i-1]的最大值+arr[i]) or dp[i] 的值本身就是最大,因为前面可能有负数,所以不一定前面的值累加就一定是最大。

3.求得最优解
值得注意的,动态转移方程只能获取当前到第i个子数组的最大值,如果要求得整个数组的最大值,我们还需要维护一个最大值maxval,来记录所有规划过程中和最大的连续子数组的值。
下面给出动态规划算法的java代码:

import java.util.*;
  
public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        //记录到下标i为止的最大连续子数组和
        int[] dp = new int[array.length];
        dp[0] = array[0];
        int maxVal = array[0];
        for(int i=1;i<array.length;i++){
            //状态转移:连续子数组和最大值
            dp[i] = Math.max(dp[i-1]+array[i],array[i]);
            //维护最大值
            maxVal = Math.max(dp[i],maxVal);
        }
        return maxVal;

根据两组案例,相信我们对动态规划一定有了深刻的了解了。

你可能感兴趣的:(算法,算法,动态规划,leetcode)