最长公共子序列(LCS)
板子-------题目:
题解:
可以用滚动数组来缩小空间,细节要注意好,比如说加重了就不要加了
#include <cstdio>
#include <iostream>
#include <cstring>
#define Mod 100000000
using namespace std;
int f[2][5005],s[5005][5005];
char st[5005],st1[5005];
int len,len1,i,j;
int main()
{
scanf("%s",st);
scanf("%s",st1);
len=strlen(st)-1;
len1=strlen(st1)-1;
for (i=1;i<=max(len1,len);i++) s[0][i]=1;
s[0][0]=s[1][0]=1;
int t;
for (i=1;i<=len;i++)
{
t=i%2;
for (j=1;j<=len1;j++)
if (st[i-1]==st1[j-1])
{
f[t][j]=f[!t][j-1]+1;
s[t][j]=s[!t][j-1];
if (f[t][j]==f[!t][j])
s[t][j]+=s[!t][j];
if (f[t][j]==f[t][j-1])
s[t][j]+=s[t][j-1];
s[t][j]%=Mod;
}
else
{
f[t][j]=max(f[!t][j],f[t][j-1]);
if (f[!t][j]>f[t][j-1])
s[t][j]=s[!t][j];
else if (f[!t][j]<f[t][j-1])
s[t][j]=s[t][j-1];
else
{
s[t][j]=s[!t][j]+s[t][j-1];
if (f[t][j]==f[!t][j-1]) s[t][j]-=s[!t][j-1];
}
s[t][j]%=Mod;
}
}
printf("%d\n%d",f[t][len1],s[t][len1]);
}
eg.-----题目:我是超链接
题解:
把这个字符串倒着存一遍,然后求两个串的最长公共子序列...........很神奇呀是不是,我居然忘了比较字符串的正确方式orz
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
struct hhh
{
int zz,i;
}tmp[105];
char st[105][505],b[505];
int f[505][505];
int cmp(hhh x,hhh y)
{
if (x.zz==y.zz) return strcmp(st[x.i],st[y.i])<0;
return x.zz>y.zz;
}
int main()
{
int i,n,j,k;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
memset(f,0,sizeof(f));
scanf("%s",st[i]);
int len=strlen(st[i]);
for (j=0;j<len;j++)
b[j]=st[i][len-j-1];
for (j=1;j<=len;j++)
for (k=1;k<=len;k++)
if (st[i][j-1]==b[k-1]) f[j][k]=f[j-1][k-1]+1;
else f[j][k]=max(f[j-1][k],f[j][k-1]);
tmp[i].zz=f[len][len];
tmp[i].i=i;
}
sort(tmp+1,tmp+n+1,cmp);
for (i=1;i<=n;i++)
printf("%s\n",st[tmp[i].i]);
}
最长公共上升子序列
代码:http://blog.csdn.net/wall_f/article/details/8279733
#include <cstdio>
#include <iostream>
using namespace std;
int a[3005],b[3005],f[3005];
int main()
{
int n,i,j,maxx=0;
scanf("%d",&n);
for (i=1;i<=n;i++) scanf("%d",&a[i]);
for (i=1;i<=n;i++) scanf("%d",&b[i]);
for (i=1;i<=n;i++)
{
int ans=0;
for (j=1;j<=n;j++)
if (a[i]>b[j] && f[j]>ans) ans=f[j];
else if (a[i]==b[j] && f[j]<ans+1) f[j]=ans+1,maxx=max(maxx,f[j]);
}
printf("%d",maxx);
}
最长公共子串
这是个后缀数组hhhh
最长公共子串