一些最长的东西(dp+后缀数组)

来源:互联网 发布:linux 禁用显卡 驱动 编辑:程序博客网 时间:2024/06/11 01:10

最长公共子序列(LCS)

板子-------题目:

我是超链接

题解:

可以用滚动数组来缩小空间,细节要注意好,比如说加重了就不要加了

#include <cstdio>#include <iostream>#include <cstring>#define Mod 100000000using 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最长公共子串

0 0
原创粉丝点击