标签:next 复杂 max pre name spl ons %s 就是
有两种字符串S,T。长度分别为n,m。现在需要在S里面有序地选出k个子串,且在T中出现的顺序与这k个子串的顺序相同。问这k个子串最大的长度和
设\(f_{k,i,j}\)表示,当前做到第\(k\)个子串,\(S\)串的第\(i\)位,\(T\)串的第\(j\)位。
那么转移就是,当\(S_{i}=T_{j}\)
\[f_{k,i,j}=\max\left\{\begin{array}\\f_{k,i-1,j-1}+1(从S的这个子串第i-1位转移过来)\\f_{k-1,i`(1<=i`<=i-1),j`(1<=j`<=j-1)}+1(从S的上一个子串第i`位转移) \end{array}\right.\]
但是,这时间复杂度是\(O(n^{2}m^{2}k)\)的。
所以,设\(mx_{k,i,j}\)表示\(\max(f_{k,i`(1<=i`<=i),j`(1<=j`<=j)})\)
那么转移改为\[f_{k,i,j}=\max\left\{\begin{array}\\f_{k,i-1,j-1}+1\\mx_{k-1,i-1,j-1}+1\end{array}\right.\]
这样,我们只要不断更新\(mx\)就可以了。
\[mx_{k,i,j}=\max\left\{\begin{array}\\mx_{k,i-1,j}\\mx_{k,i,j-1}\\f_{k,i,j}\end{array}\right.\]
时间复杂度是\(O(nmk)\)
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=1005;
using namespace std;
int g[N][N],n,m,k,tot,ans,next[N],f[12][N][N],mx[12][N][N];
char s[N],t[N];
int main()
{
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
scanf("%d%d%d\n",&n,&m,&k);
scanf("%s\n",s+1);
scanf("%s\n",t+1);
for(int l=1;l<=k;l++)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(s[i]==t[j])
{
f[l][i][j]=max(f[l][i-1][j-1],mx[l-1][i-1][j-1])+1;
}
mx[l][i][j]=max(mx[l][i][j-1],max(mx[l][i-1][j],f[l][i][j]));
ans=max(ans,f[l][i][j]);
}
printf("%d",ans);
}
标签:next 复杂 max pre name spl ons %s 就是
原文地址:https://www.cnblogs.com/chen1352/p/9013478.html