动态规划(DP)问题分析汇总

Posted 月牙儿June

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划(DP)问题分析汇总相关的知识,希望对你有一定的参考价值。

问题1:

LeetCode 53. Maximum Subarray求最小和

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example, given the array [-2,1,-3,4,-1,2,1,-5,4],
the contiguous subarray [4,-1,2,1] has the largest sum = 6.


分析:题目属于最优化问题,最优化问题通常用动态规划思想解决。

动态规划的要点:划分成子问题(尤其是在利用递归来解决问题时,注意这里的递归不一定非要以函数递归的形式来实现,也可以用 循环来实现(且优先使用  循环的形式)通过将先计算出的结果保存下来如保存f( i-1)、f(i-2)...等的结果,在下一次循环时直接用就行)。

就本题来说,我们很容易想到可以将原问题划分为求 maxSubArray(int A[] ,int i,int j).最终只要求出maxSubArray(A,0,a.length-1)即可。但是,我却很难找到原问题与子问题之间的关系,也就是说,难以将原问题划分为子问题来求解。因此,换一种思维,将子问题定义为: maxSubArray(int A[] ,int i),求子数组[ 0 , i ]中的最大和,且必须包含A[i]作为连续数组的结尾。

原问题就可以按以下方式分解:

 maxSubArray( A , i)=(maxSubArray(A,i-1)>0?maxSubArray(A,i-1):0 )+ A[i];

问题迎刃而解

Java代码:

public class Solution 
    public int maxSubArray(int[] nums) 
        if(nums==null) return 0;
        int last=nums[0];
        int max=last;
        
        for(int i=1;i<nums.length;i++)
            last=(last>0?last:0 ) + nums[i];
            max=Math.max(max,last);
        
        return max;
    


问题2

LeetCode 62. Unique Paths求路径条数

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?


Above is a 3 x 7 grid. How many possible unique paths are there?

Note: m and n will be at most 100.


分析:建立一个二维数组保存以arr[i][j]为finish的路径数目,则原问题可以通过以下方式解决:

arr[i][j]=a[i][j-1](当前位置的左边)+a[i-1][j] (当前位置的上边)

写代码时先把一些特殊情况、初始情况、边界情况先列出来。然后再从(i=1,j=1)的一般情况开始,在初始边界情况的基础上,进行循环递归。

java代码:

public class Solution 
    public int uniquePaths(int m, int n) 
        if(m==0 && n==0) return 0;
        if(m==1 && n==1) return 1;
        int rst=0;
        int[][] arr=new int [m][n];
        arr[0][0]=0;
        for(int i=1;i<m;i++)
            arr[i][0]=1;
        
        for(int j=1;j<n;j++)
            arr[0][j]=1;
        
        for(int i=1;i<m;i++)
            for(int j=1;j<n;j++)
                arr[i][j]=arr[i][j-1]+arr[i-1][j];
             
        
        return arr[m-1][n-1];
    


问题2的升级版:

LeetCode 63. Unique Paths II

Follow up for "Unique Paths":

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

For example,

There is one obstacle in the middle of a 3x3 grid as illustrated below.

[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]

The total number of unique paths is 2.

Note: m and n will be at most 100.

分析:在上个问题的基础上添加了障碍物。只需把障碍物的情况考虑进去即可。

Java代码:

public class Solution 
    public int uniquePathsWithObstacles(int[][] obstacleGrid) 
        if(obstacleGrid==null) return 0;
        int m=obstacleGrid.length;
        int n=obstacleGrid[0].length;
        if(obstacleGrid[0][0]==1) return 0;
        if(m==1 && n==1)
            return 1;
         
        int rst=0;  
        int[][] arr=new int [m][n];  
        arr[0][0]=0;  
        for(int i=1;i<m && obstacleGrid[i][0]==0;i++)
            arr[i][0]=1;  
          
        for(int j=1;j<n && obstacleGrid[0][j]==0;j++)  
            arr[0][j]=1;  
          
        for(int i=1;i<m;i++)  
            for(int j=1;j<n;j++) 
                if(obstacleGrid[i][j]==1) arr[i][j]=0;
                else
                   arr[i][j]=arr[i][j-1]+arr[i-1][j];  
               
          
        return arr[m-1][n-1];  
    


以上是关于动态规划(DP)问题分析汇总的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 1289. 下降路径最小和 II

CSP 202104-4 校门外的树 python 动态规划DP + 约数优化

信件错排问题分析(动态规划)

动态规划

bzoj1814: Ural 1519 Formula 1 动态规划 插头dp

leetcode 931. 下降路径最小和