题目
描述
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, …, xm > another sequence Z = < z1, z2, …, zk > is a subsequence of X if there exists a strictly increasing sequence < i1, i2, …, ik > of indices of X such that for all j = 1,2,…,k, xij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
输入
The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.
输出
For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
样例输入
abcfbc abfcab
programming contest
abcd mnp
样例输出
4
2
0
思路
是道动规题。没想出来,笨办法做的,将某一个字符串作为标准(最大问题),右侧n个的最大子串作为子问题,与另一个子串进行比较。比较耗时。题目没给范围,略坑,只能自己猜一个范围。
#include <stdio.h>
#include <algorithm>
#include <string>
using namespace std;
string s1,s2;
int last[100000];
int fun(int & p1, int & p2, int l){
if(p2>=s2.size() || p1>=s1.size())
return l;
int t= p2;
for(;p1<s1.size();p1++){
for(;p2<s2.size();p2++){
if(s1[p1]==s2[p2])
l = fun(++p1,++p2,l+1);
if(p1>=s1.size())
break;
}
p2 = t;
}
return l;
}
int main()
{
freopen("1.txt","r",stdin);
char a1[10000],a2[10000];
int t2 =0;
int j;
while(scanf("%s%s",a1,a2)==2){
s1 = a1;
s2 = a2;
for(int i=0;i<s1.size();i++){
t2 =0;
j = i;
last[i] = fun(j,t2,0);
}
int t =0;
for(int i=0;i<s1.size();i++){
t = max(t,last[i]);
}
printf("%d\n",t);
}
return 0;
}
动规作法,时间是上一种的十分之一
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
char a1[1000],a2[1000];
int last[1000][1000];
int main(){
freopen("1.txt","r",stdin);
while(scanf("%s %s",a1,a2)==2){
int len1 = strlen(a1);
int len2 = strlen(a2);
for(int i=0;i<=len1;i++){
last[i][0] = 0;
}
for(int i=0;i<=len2;i++){
last[0][i]=0;
}
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
if(a1[i]==a2[j]){
last[i+1][j+1] = last[i][j]+1;
}else{
last[i+1][j+1] = max(last[i+1][j],last[i][j+1]);
}
}
}
printf("%d\n",last[len1][len2]);
}
}
两种方法的比较
- 第一种只记录了一维最值,相当于没有打表,会不停的反复计算;第二种记录了二维的最值。