动归题目分类汇总
2015-01-13 00:33
204 查看
dp (包括递归)的思路是间接的,即不是直接的针对题目设计具体算法,而是递归,即规模为小的解直接知道,大规模的解是较小规模解的函数,一步一步递推而来。形象的可以说为填表法,第一个表项(一维表)或者第一行第一列(二维表)已知,其余表项可以一步一步推出来。
动规三要素
1)状态定义
2)状态转移方程,递推关系,
3)初始化,
九章的分类:
1 Matrix DP 代表题目
1)Number Triangle: 从三角顶到底边的路径最小和
状态定义:f[i][j] 为 从位置(i,j)到底边的路径最小和
递推式:f[i][j] = min(f[i + 1][j], f[i + 1][j + 1]) +triangle[i][j]
初始化:最后一行和三角形底边一致
2) Unique Path :一个矩阵,从左上角走到右下角的路径数
状态定义:f[i][j]为从(0,0)走到位置(i,j)的路径数
递推式:f[i][j] = f[i - 1][j] + f[i][j - 1]
初始化:第一行和第一列都是1
3) Unique Path II: 同上,但是矩阵里有些block site
递推式:f[i][j] = matrix[i][j] == 1 ? 0 : f[i - 1][j] + f[i][j + 1]
4) Minimum Path sum:求矩阵左上角到右下角的最小path sum,和Number Triangle很像
状态定义:f[i][j] 为左上角到位置(i, j)到path sum。
递推式:f[i][j] = min( f[i - 1][j], f[i][j - 1]) + matrix[i][j]
2 Sequence DP
1)Jump Game:是否能从A[0] 跳到A[n - 1]
状态定义:f[i]为是否能从A[0]跳到A[i]
递推式:f[i] = any( f[j] && A[j] >= i - j ) for j < i
初始化:f[0] = true
答案:f[n - 1]
2)Jump Game II 从A[0] 跳到A[n - 1] 最少多少步?
状态定义:f[i] 为 从A[0]跳到A[i] 最少多少步
递推式:f[i] = min( f[j] ) + 1 for j < i and A[j] >= i - j
初始化:f[0] = 0
解:f[n - 1]
3) Palindrome Partitioning II: 把一个字符串分割成全部是回文的子串最少需要多少次cut
状态定义:f[i] 为 s[i, n)分成回文子串的最少cut数
递推式:f[i] = min ( f [j+1] + 1) for j >= i and j < n and s[i, j] 是回文
解:f[0]
4)Word Break:给定一个字符串和一个词典,问字符串是否能被完美分割为词典中的词
状态定义:f[i]为 前i个字符的串是否可以被完美分割
递推式:f[i] = any (s [j, i) is in the dict and f [j] == true ) for j < i and i - j 在词典单词长度范围内
初始化:f[0] = true
答案:f
5) LIS 问题
状态定义:f[i] 为以A[i] 结尾的最长递增子序列长度
递推式:f[i] = max (f [j] + 1) for j < i and A[i] >= A[j]
初始化:f[0] = 1
答案:max { f[i] + 1}, i = 0,...n - 1
3 Two Sequences DP
1) Longest Common Subsequence
状态定义:f[i][j] 为 s1 前i个字符的子串和s2前j个字符的子串的最长公共子序列
递推式:f[i][j] = f[i-1][j-1] + 1, when s1 [ i - 1] == s2 [j - 1]
f[i][j] = max ( f [i - 1] [ j], f [i][j - 1]), when s1[i-1] != s2[j-1]
初始化: 第一行和第一列为 0
答案:f[s1.size()][s2.size()]
2) Longest Common Substring
状态定义:f[i][j] 为s1的以第i个字符结尾的子串和s2的以第j个字符结尾的子串的最长公共子串长度
递推式:if s1[i-1] == s2[j-1], f[i][j] = f[i-1][j-1] + 1
else f[i][j]= 0
初始化:第一行和第一列为0
答案:max{ f[i][j] }
3) Edit Distance
状态定义:f[i][j] 为s1的前i个字符的子串和 s2的前j个字符的子串的编辑距离
递推式:f[i][j] = f[i-1][j-1],when s1[i-1] == s2[j-1]
f[i][j] = min ( f[i-1][j-1] + 1, f[i][j-1] + 1, f[i-1][j] + 1 ), when s1[i-1] != s2[j-1]
初始化:第一行 每个元素值为列号j,第一列每个元素值为行号i
答案:f[s1.size()][s2.size()]
4) Distinct subsequences: 用一个字符串S的子序列构造另一个字符串T,有多少种方案?
状态定义:f[i][j]为 用S的前i个字符构的子序列构造T的前j个字符的子串的方案数
递推式:f[i][j] = f[i-1][j-1] + f[i-1][j], when S[i-1] == T[j-1]
f[i][j] = f[i-1][j], when S[i-1] != T[j-1]
初始化:第一行为0,但f[0][0] = 1,第一列为1(空串就用空子序列构造,总有一个方案)
答案:f[S.size()][T.size()]
5) Interleaving String:问一个字符串c是否可以用分别从字符串a、b取字符的方式构建
状态定义:f[i][j] 为 a的前i个字符的子串和b的前j个字符的子串是否可以构建出c的前i + j个字符的子串
递推式:f[i][j] = f[i-1][j] && a[i-1] == c[i+j-1] || f[i][j-1] && b[j-1] == c[i+j-1]
初始化:f[0][0] = true, 第一行其余部分 为 f[0][j] = b[j-1] == c[j-1], 第一列其余部分为f[i][0] = a[i-1] == c[i-1]
答案:f[a.size()][b.size()]
4 Backpack DP
动规三要素
1)状态定义
2)状态转移方程,递推关系,
3)初始化,
九章的分类:
1 Matrix DP 代表题目
1)Number Triangle: 从三角顶到底边的路径最小和
状态定义:f[i][j] 为 从位置(i,j)到底边的路径最小和
递推式:f[i][j] = min(f[i + 1][j], f[i + 1][j + 1]) +triangle[i][j]
初始化:最后一行和三角形底边一致
2) Unique Path :一个矩阵,从左上角走到右下角的路径数
状态定义:f[i][j]为从(0,0)走到位置(i,j)的路径数
递推式:f[i][j] = f[i - 1][j] + f[i][j - 1]
初始化:第一行和第一列都是1
3) Unique Path II: 同上,但是矩阵里有些block site
递推式:f[i][j] = matrix[i][j] == 1 ? 0 : f[i - 1][j] + f[i][j + 1]
4) Minimum Path sum:求矩阵左上角到右下角的最小path sum,和Number Triangle很像
状态定义:f[i][j] 为左上角到位置(i, j)到path sum。
递推式:f[i][j] = min( f[i - 1][j], f[i][j - 1]) + matrix[i][j]
2 Sequence DP
1)Jump Game:是否能从A[0] 跳到A[n - 1]
状态定义:f[i]为是否能从A[0]跳到A[i]
递推式:f[i] = any( f[j] && A[j] >= i - j ) for j < i
初始化:f[0] = true
答案:f[n - 1]
2)Jump Game II 从A[0] 跳到A[n - 1] 最少多少步?
状态定义:f[i] 为 从A[0]跳到A[i] 最少多少步
递推式:f[i] = min( f[j] ) + 1 for j < i and A[j] >= i - j
初始化:f[0] = 0
解:f[n - 1]
3) Palindrome Partitioning II: 把一个字符串分割成全部是回文的子串最少需要多少次cut
状态定义:f[i] 为 s[i, n)分成回文子串的最少cut数
递推式:f[i] = min ( f [j+1] + 1) for j >= i and j < n and s[i, j] 是回文
解:f[0]
4)Word Break:给定一个字符串和一个词典,问字符串是否能被完美分割为词典中的词
状态定义:f[i]为 前i个字符的串是否可以被完美分割
递推式:f[i] = any (s [j, i) is in the dict and f [j] == true ) for j < i and i - j 在词典单词长度范围内
初始化:f[0] = true
答案:f
5) LIS 问题
状态定义:f[i] 为以A[i] 结尾的最长递增子序列长度
递推式:f[i] = max (f [j] + 1) for j < i and A[i] >= A[j]
初始化:f[0] = 1
答案:max { f[i] + 1}, i = 0,...n - 1
3 Two Sequences DP
1) Longest Common Subsequence
状态定义:f[i][j] 为 s1 前i个字符的子串和s2前j个字符的子串的最长公共子序列
递推式:f[i][j] = f[i-1][j-1] + 1, when s1 [ i - 1] == s2 [j - 1]
f[i][j] = max ( f [i - 1] [ j], f [i][j - 1]), when s1[i-1] != s2[j-1]
初始化: 第一行和第一列为 0
答案:f[s1.size()][s2.size()]
2) Longest Common Substring
状态定义:f[i][j] 为s1的以第i个字符结尾的子串和s2的以第j个字符结尾的子串的最长公共子串长度
递推式:if s1[i-1] == s2[j-1], f[i][j] = f[i-1][j-1] + 1
else f[i][j]= 0
初始化:第一行和第一列为0
答案:max{ f[i][j] }
3) Edit Distance
状态定义:f[i][j] 为s1的前i个字符的子串和 s2的前j个字符的子串的编辑距离
递推式:f[i][j] = f[i-1][j-1],when s1[i-1] == s2[j-1]
f[i][j] = min ( f[i-1][j-1] + 1, f[i][j-1] + 1, f[i-1][j] + 1 ), when s1[i-1] != s2[j-1]
初始化:第一行 每个元素值为列号j,第一列每个元素值为行号i
答案:f[s1.size()][s2.size()]
4) Distinct subsequences: 用一个字符串S的子序列构造另一个字符串T,有多少种方案?
状态定义:f[i][j]为 用S的前i个字符构的子序列构造T的前j个字符的子串的方案数
递推式:f[i][j] = f[i-1][j-1] + f[i-1][j], when S[i-1] == T[j-1]
f[i][j] = f[i-1][j], when S[i-1] != T[j-1]
初始化:第一行为0,但f[0][0] = 1,第一列为1(空串就用空子序列构造,总有一个方案)
答案:f[S.size()][T.size()]
5) Interleaving String:问一个字符串c是否可以用分别从字符串a、b取字符的方式构建
状态定义:f[i][j] 为 a的前i个字符的子串和b的前j个字符的子串是否可以构建出c的前i + j个字符的子串
递推式:f[i][j] = f[i-1][j] && a[i-1] == c[i+j-1] || f[i][j-1] && b[j-1] == c[i+j-1]
初始化:f[0][0] = true, 第一行其余部分 为 f[0][j] = b[j-1] == c[j-1], 第一列其余部分为f[i][0] = a[i-1] == c[i-1]
答案:f[a.size()][b.size()]
4 Backpack DP
相关文章推荐
- 【南阳OJ分类之语言入门】80题题目+AC代码汇总
- 【转】poj pku 线段树题目20道汇总+简要算法+分类+难度
- 【南阳OJ分类之语言入门】80题题目+AC代码汇总
- 随机数生成问题分类以及题目汇总
- POJ 线段树题目20道汇总+简要算法+分类+难度
- 【南阳OJ分类之大数问题】题目+AC代码汇总
- poj pku 线段树题目20道汇总+简要算法+分类+难度
- GitHub上史上最全的Android开源项目分类汇总
- Android开源项目分类汇总
- Linux常用命令分类汇总(2)
- Android开源项目分类汇总
- 机器学习常见算法分类汇总
- 程序员工作面试题目汇总
- C语言课程设计题目汇总
- Android开源项目--分类汇总
- 杭电题目分类
- 编程题目分类
- C/C++ 笔试、面试题目大汇总2
- Web前端面试题目记答案汇总
- 计算机网络---基础题目汇总四