线性dp的经典问题:LIS、LCS、数字三角形。
最长上升子序列(LIS)
问题描述: 给定一个长度为N的数列A,求数值单调递增的子序列的长度最长是多少。A的任意子序列可表示为B = {Ak1, Ak2, …, Akp},其中k1<k2<…<kp。
状态表示: F[i]表示以A[i]为结尾的“最长上升子序列”的长度
阶段划分: 子序列的结尾位置(数列A中的位置,从前到后)
转移方程: F[i] = max{ F[j] + 1 }, j<i,A[j]<A[i]
边界: F[0] = 0
目标: max{ F[i] } 1<=i<=N
最长公共子序列(LCS)
问题描述: 给定两个长度分别为N和M的自负床A和B,求既是A的子序列又是B的子序列的字符串长度最长是多少。
状态表示: F[i, j]表示前缀子串A[1 ~ i]与B[1 ~ j]的“最长公共子序列”的长度
阶段划分:
已经处理的前缀长度(两个字符串中的位置,即一个二维坐标)
转移方程:
f[i, j] = max {
F[i - 1, j],
F[i, j - 1],
F[i - 1, j - 1] + 1 if: A[i] = B[j]
}
边界: F[i, 0] = F[0, j] = 0
目标: F[N, M]
数字三角形
问题描述: 给定一个共有N行的三角矩阵A,其中第i行有i列不为零。从左上角出发,每次可以向下方或右下方走一步,最终到达底部。求把经过的所有位置上的数加起来,和最大是多少。
状态表示: F[i, j]表示从左上角走到第i行第j列,和最大是多少
阶段划分: 路径的结尾位置(矩阵中的行、列位置,即一个二维坐标)
转移方程:
F[i, j] = A[i, j] + max {
F[i - 1, j],
F[i - 1, j - 1] if: j > 1
}
边界: F[1, 1] = A[1, 1]
目标: max { F[N, j] } 1<=j<=N