第一部分 最长上升子序列,最长上升子串,最长公共子序列,最长公共子串--dp
第二部分 KMP,trie,双指针
第三部分 待定
动态规划:审题,状态确定,状态转移,边界条件
线性DP
最长上升子序列
403 线性DP 最长上升子序列【动态规划】_哔哩哔哩_bilibili
给定一个无序整数数组,找出其中最长上升子序列(LIS)的长度。
输入:【5,7,1,9,4,6,2,8,3】
输出:4
解释:最长上升子序列是【1,4,6,8】,其长度是4
如何思考解决这个问题,用s表示这个数组,设f(i)表示以s[i]结尾的的最长上升子序列长度,边界条件f(0)=1,思考当i>=1时,f(i)与f(i-1)的关系,考虑s[i]和s[i-1],或者考虑s[i]与s[0]...s[i-1],至少有一点,f(i)大于等于f(i-1),遍历s[0]...s[i-1],如果记录最大的j,使得s[j]<s[i],且j尽可能大,f(i)=max(f(i-1),f(j)+1),该递推式有问题,修正,f(i)=max(f(i),f(j)+1),这样就没有问题了,
比如5,7,1,9,4,6,2,8,3
f(0)=1,f(1)=2,f(2)=1,f(3)=f(2)+1=3,f(4)=2,f(5)=3,f(6)=2,f(7)=4,f(8)=3
上述的过程是可行的,记录最大的f(i)即可,就是答案,如果f(i)表示以s[i]结尾的子串的最长上升子序列,那么显然有f(i)大于f(i-1),但是难以列出状态转移方程。
另外,设f(i)表示以s[i]开头的最长上升子序列长度,从后往前遍历,对于5,7,1,9,4,6,2,8,3 这列数,一共9个数,数组下标从0开始,初始条件f(8)=1,当s[i]<s[i+1]时,更新f(i)=max(f(i),f(i+1)+1),
最长上升序列求解,重点在于如何将状态函数与字符串之间的关系唯一确定下来,如果采用以s[i]结尾的最长公共子序列长度作为f(i)的含义,从前往后搜索,可以得到转换公式;如果采用以s[i]开头的最长公共子序列长度作为f(i)的含义,改变搜索方向,同样可以得到转换的公式。如果采用s[0]...s[i]的最大上升子序列长度作为f(i)的含义,很难得到转换公式,f(i)的值(但是这个是根据题目含义最容易想的状态含义,难以求解出状态转移方程)
如何确定状态函数的含义
定义f(i)表示爬到高度为i时需要的期望时间,由高度i-1可以转换为两个状态,分别是高度0,概率是pi;转换为高度i,概率是1-pi;在上述定义下,难以写出转换方程
定义f(i)为从高度为i爬到树顶需要的期望时间,则f(树高度)=0,状态转移是,f(i-1)=(1-pi)*f(i)+pi*f(0)+1,需要求解的就是从树的底部(高度为0)爬到树顶经过的时间的期望值f(0).
最长公共子序列
给定两个字符串,输出其最长公共子序列的长度,输入,ADABEC与DBDCA
输出:3
解释:最长公共子序列是DBC,长度是3
从左向右扫描两个字符串a,b,指针分别使用i和j,状态变量,看作自变量i和j的函数,数据结构实现可以使用二维数组,f(i,j)表示a[0]...a[i]与b[0]...b[j]的最长公共子序列长度,f(0,0)=0,状态转移方程,如果a[i]=b[j],有f(i,j)=f(i-1,j-1)+1,如果a[i]!=b[j],分为三种情况,分别是a[i]不在最长公共子序列中,f(i,j)=f(i-1,j),b[j]不在最长公共子序列中,f(i,j)=f(i,j-1),a[i]和b[j]都不在最长公共子序列中,f(i,j)=f(i-1,j-1),其中第三种可以看成前两种的特例,如果a[i]!=b[j]有f(i,j)=max(f(i-1,j),f(i,j-1));
最长上升子串
参考最长上升子序列做法,设f(i)表示以s[i]结尾的最长上升子串的长度,f(0)=0,如果s[i]>s[i-1],f(i)=f(i-1)+1,否则f(i)=0;最长上升子串长度是最大的f(j),j=0,1,...,n-1.
最长公共子串
参考最长公共子序列做法,设f(i,j)表示a[0]...a[i]和b[0]...b[j]的最长公共子串的长度,f(0,0)=0,如果a[i]!=b[j],f(i,j)=0;如果a[i]==b[j],则f(i,j)=f(i-1,j-1)+1;
只有当两个字符串中的字符连续相等时,公共字串的长度才不断增加。
最长上升公共子串
参考最长公共子序列做法,设f(i,j)表示a[0]...a[i]和b[0]...b[j]的最长公共子串的长度,f(0,0)=0,如果a[i]!=b[j],f(i,j)=0;如果a[i]>a[i-1]且b[j]>b[j-1]且a[i]==b[j]且a[i-1]==b[j-1],则f(i,j)=f(i-1,j-1)+1;如果a[i]==b[j]且a[i-1]==b[j-1]且a[i]>a[i-1],则f(i,j)=f(i-1,j-1)+1;否则,如果a[i]==b[j],则f(i,j)=1;,否则f(i,j)=0.
最长上升公共子序列