额,比较基础的模板题,求最长公共子序列
这里用滚动数组来保存中间值,因为只需要保存相邻俩行的值.
pku的1936只需要加一步判断即可,判断最长公共子序列长度是否等于s1 的长度
递推公式为:
if(s1[i]==s2[j]) c[i,j]=c[i-1,j-1]+1;
else c[i,j]=max(c[i-1,j],c[i,j-1])
pku1936
#include<iostream> #include<string> #include<algorithm> #define maxn 100005 using namespace std; char s1[maxn],s2[maxn]; int s[maxn],t[maxn]; int main() { int l1,l2; while(scanf("%s %s",s1,s2)==2) { l1=strlen(s1); l2=strlen(s2); memset(s,0,sizeof(s)); memset(t,0,sizeof(t)); for(int i=0;i<l1;i++) { for(int j=0;j<l2;j++) { if(s1[i]==s2[j]) s[j+1]=t[j]+1; else s[j+1]=t[j+1]>s[j]?t[j+1]:s[j]; } for(int j=1;j<=l2;j++) t[j]=s[j]; } if(t[l2]==l1) printf("Yes\n"); else printf("No\n"); } return 0; }
hdu1159
#include<iostream> #include<string> #include<algorithm> using namespace std; int main() { char s1[1000],s2[1000]; int s[1000],t[1000],l1,l2; while(scanf("%s %s",s1,s2)==2) { l1=strlen(s1); l2=strlen(s2); memset(s,0,sizeof(s)); memset(t,0,sizeof(t)); for(int i=0;i<l1;i++) { for(int j=0;j<l2;j++) { if(s1[i]==s2[j]) s[j+1]=t[j]+1; else s[j+1]=t[j+1]>s[j]?t[j+1]:s[j]; } for(int j=1;j<=l2;j++) t[j]=s[j]; } printf("%d\n",t[l2]); } return 0; }