牛客每日一题3月
目录:
3.26 NC13230.合并回文子串(区间DP)
3.27 NC15553.数学考试(线性DP)
NC13230.合并回文子串(区间DP)
题意:
给两个字符串a,b,你需要将两个字符串合并,并且保证新字符串中原来字符串的相对位置不变,求合并之后字符串最长回文子序列的长度
思路:
首先,先要了解一下如果求一个字符串的最长回文子序列问题这也是一个经典的区间DP问题
我们知道回文串是个左右对称的结构,所以一个回文串的增加长度是通过左右两边各加一个相同字母来实现的
所以,我们倾向于把子问题描述成:“字符串 s 的第 i 个字符到第 j 个字符的最长回文子序列长度”,
那么我们就用dp数组来表示它——dp[i][j为字符串 s 的第 i 个字符到第 j 个字符的最长回文子序列长度。
那么如何进行转移呢,可以看到字符串在向两端拓展时,会遇到以下两种情况
①s[i] == s[j]:这个时候可以把s[i]和s[j]分别加到原来0的回文子序列的两端,也就是 i+1 到 j-1 这个区间的字符构成的最长回文子序列的两端,此时 dp[i][j]=dp[i+1][j−1]+2
②s[i] != s[j]:那么在 i 到 j 这个区间的最长回文子序列中第 i 个字符和第 j 个字符一定不能同时存在,所以是可以扔掉他俩中的某一个的(并不是任意一个),此时 dp[i][j]=max(dp[i+1][j],dp[i][j−1])
之后就可以回到原来的问题了
我们定义dp[i][j][k][l]为表示前一个串(a串)的第 i 个字符到第 j 个字符后一个串(b串)的第 k 个字符到第 l 个字符能否组成一个回文串的话,有四种可能,四种当中任意一种为真f[i][j][k][l]就是真。
①往 a[i+1] 到 a[j−1] 和 b[k] 到 b[l] 构成的串的两端加上 a[i] 和 a[j] 两个字符:f[i][j][k][l]∣=(f[i+1][j−1][k][l]&(a[i]==a[j]));
②往 a[i+1] 到 a[j] 和 b[k] 到 b[l−1] 构成的串的两端加上 a[i] 和 b[l−1] 两个字符:f[i][j][k][l]∣=(f[i+1][j][k][l−1]&(a[i]==b[l]));