【Leetcode】动态规划问题详解(持续更新)

1、动态规划算法步骤(Dynamic Programming)

动态规划算法一般用来求解最优化问题,当问题有很多可行解,而题目要求寻找这些解当中的“最大值”/“最小值”时,通常可以采用DP。

动态规划算法与分治法相似,都是通过组合子问题的解来求解原问题。所不同的是,动态规划应用于子问题重叠的情况,在递归求解子问题的时候,一些子子问题可能是相同的,这种情况下,分治法会反复地计算同样的子问题,而动态规划对于相同的子问题只计算一次。

动态规划算法的设计步骤

1、刻画最优解的结构特征(寻找最优子结构)

2、递归地定义最优解的值(确定递归公式)

3、计算最优解的值(有两种方法:带备忘录自顶向下法、自底向上法)

4、利用计算出的信息构造一个最优解(通常是将具体的最优解输出)

2、leetcode上适合用DP求解的问题

题目 OJ地址 目录  

Triangle

https://oj.leetcode.com/problems/triangle/  3.1
Maximum Subarray https://oj.leetcode.com/problems/maximum-subarray/ 3.2

Palindrome Partitioning II

https://oj.leetcode.com/problems/palindrome-partitioning-ii/ 3.3
Minimum Path Sum https://oj.leetcode.com/problems/minimum-path-sum/ 3.4
Maximal Rectangle https://oj.leetcode.com/problems/maximal-rectangle/ 3.5

Interleaving String

https://oj.leetcode.com/problems/interleaving-string/ 3.6
Edit Distance https://oj.leetcode.com/problems/edit-distance/ 3.7

Decode Ways

https://oj.leetcode.com/problems/decode-ways/ 3.8

Best Time to Buy and Sell Stoc

I&II&III

https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock/ 3.9

Scramble String

https://oj.leetcode.com/problems/scramble-string/ 3.10

Distinct Subsequences

https://oj.leetcode.com/problems/distinct-subsequences/ 3.11
Word Break I&II https://oj.leetcode.com/problems/word-break/ 3.12

3、leetcode相关题目

3.1 Triangle

3.1.1 题目

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 =
11).

Note:

Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

3.1.2 分析

题目大意:从最顶端往下走,寻找和最小的路径。

显然,从最顶端往下走有很多条路径可以走,但是每一条路径的sum不一样,题目要求sum最小,属于最优化问题,考虑动态规划。

如果用暴力破解,复杂度如何?观察题目所给的三角形,对于每个“节点”,往下都有两条路可以走,比如2可以往3、4走,3可以往6、5走,4可以往5、7走.......类似于二叉树,如果有n行,则一共有路径2^n条,时间复杂度O(2^n)。

动态规划的话,时间复杂度可以降到O(n^2)。下面按照动态规划的步骤来分析这道题:

#1 最优解的结构特征

第一个步骤要搞清楚怎么将问题分解为更小的子问题。上面已经提到,“2”往下走都有两条路可以选择,分别是“3”、“4”,因此从2出发的最优路径,其实就是从“3”出发的最优路径、从“4”出发的最优路径  这两者中sum最小的一条。

#2 确定递归求解公式

用f(i,j)表示从点(i,j)出发的最优路径的sum,根据上面分析,易得递归公式 :f(i,j)=min{f(i+1,j),f(i+1,j+1)}+Val(i,j)

Val(i,j)表示点(i,j)的值。

#3 根据递归公式求解

分别用“自底向上”、“带备忘录的自顶向下”两种方法,见3.1.3代码

3.1.3 参考代码

自底向上法,注意到f(0,0)取决于f(1,0)、f(1,1);  f(1,0)又取决于f(2,0)、f(2,1)......所以从最底层开始计算是比较自然的做法,而最底层的最短路径和就是节点本身的值,因此实际上是从倒数第二层开始计算。

 int minimumTotal(vector<vector<int> > &triangle) {
        int row=triangle.size();    //行,第row行的元素有row个
        vector<vector<int> > f(triangle);
        //用f[m][n]记录从triangle[m][n]出发到叶子节点的最短路径和。也可以直接用triangle代替f,但会改变triangle

        for(int x=row-2;x>=0;x--)
           for(int y=0;y<=x;y++)
              f[x][y]=min(f[x+1][y],f[x+1][y+1])+triangle[x][y];
        return f[0][0];
    }

带备忘录的自顶向下法

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        int row=triangle.size();    //行
        vector<vector<int> > f(triangle);   //f[m][n]表示从triangle[m][n]出发到叶子节点的最短路径和
        for(int m=0;m<row-1;m++)
           for(int n=0;n<=m;n++)
              f[m][n]=INT_MAX;         //与自底向上的方法不同,备忘录法必须将其初始化为标识值,以便“查找备忘录”
	f[row-1]=triangle[row-1];       //最后一行保持原值
        return dp(0,0,triangle,f);      //从根出发
    }
private:
   int dp(int x,int y,vector<vector<int> > &triangle,vector<vector<int> > &f){
        if(f[x][y]!=INT_MAX) return f[x][y];   //查找备忘录,如果已经计算过,直接返回,避免重复计算
        f[x][y]=min(dp(x+1,y,triangle,f),dp(x+1,y+1,triangle,f))+triangle[x][y];
        return f[x][y];
   }
};

时间: 2024-07-30 17:03:43

【Leetcode】动态规划问题详解(持续更新)的相关文章

LeetCode动态规划题总结【持续更新】

以下题号均为LeetCode题号,便于查看原题. 10. Regular Expression Matching 题意:实现字符串的正则匹配,包含'.' 和 '*'.'.' 匹配任意一个字符,"*" 匹配 '*' 之前的0个或多个字符. example: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa",&

Sublime Text 3 使用详解(持续更新)

安装Sublime Text 3插件的方法: 直接安装 安装Sublime text 3插件很方便,可以直接下载安装包解压缩到Packages目录(菜单->preferences->packages). 使用PACKAGE CONTROL组件安装(一般使用这种方法安装) 也可以安装package control组件,然后直接在线安装: 英文网站(https://packagecontrol.io/installation#Simple) package control 是用来安装其它插件的插件

Icehouse版keystone配置完全详解(更新中)

本文全面解读Icehouse发行版keystone的配置文件keystone.conf [DEFAULT]admin_token=(string value)# 这是一个公知的密码,用于初始化keystone,强烈建议在生产模式中禁用,只需要在# keystone-paste.ini文件中移除AdminTokenAuthMiddleware这个pipeline即可 public_bind_host=(string value)# The IP Address of the network int

(转)dp动态规划分类详解

dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. ****************************************************************************************** 动态规划(英语:Dynamic programm

MVC之Ajax.BeginForm使用详解之更新列表

1.首先,请在配置文件设置如下:(该项默认都存在且为true) <add key="UnobtrusiveJavaScriptEnabled" value="true" /> 2.在你的_layout.cshtml中引入JS文件: <script src="~/Scripts/jquery-1.8.2.min.js"></script> <script src="~/Scripts/jquery

动态规划思想详解及示例实现

本文以两个具体例子详细剖析动态规划算法设计思想,主要参考圣经<算法导论>,加上自己的一些理解,主要是附上了一些具体实现过程,所以希望能对大家有所帮助. #_*_ coding:utf-8 _*_ import numpy as np def MemoizedCutRodAux(p,n,r,s): if r[n]>=0: return r[n] if n==0: q=0 c=0 else: q=-1 c=-1 for i in range(1,n+1): if q<(p[i]+Mem

HDU 5366 The mook jong (动态规划,详解)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5366 题面: The mook jong Accepts: 221 Submissions: 306 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description ZJiaQ want to become a strong man, so he decided

java-core:ClassLoader详解,更新1

先来看一个例子: package core.java; class SingleTon{ private static SingleTon instance = new SingleTon(); public static int num1; public static int num2 = 0; private SingleTon(){ num1++; num2++; } public static SingleTon getInstance(){ return instance; } } p

LeetCode Animation 题目图解汇总(持续更新中...)

我会尽力将LeetCode上所有的题目都用动画的形式演示出来,期待与你见证这一天! GitHub Repo:LeetCode Animation Follow: MisterBooo · GitHub Problems ID Problem Article Animation 001 两数之和 每天一算:Two Sum 019 删除链表的倒数第N个节点 每天一算:Remove Nth Node From End of List 020 有效的括号 每天一算:Valid Parentheses 0