Aizu - ALDS1_10_C Longest Common Subsequence【dp】

For given two sequences XX and YY, a sequence ZZ is a common subsequence of XX and YYif ZZ is a subsequence of both XX and YY. For example, if X={a,b,c,b,d,a,b}X={a,b,c,b,d,a,b} and Y={b,d,c,a,b,a}Y={b,d,c,a,b,a}, the sequence {b,c,a}{b,c,a} is a common subsequence of both XX and YY. On the other hand, the sequence {b,c,a}{b,c,a} is not a longest common subsequence (LCS) of XXand YY, since it has length 3 and the sequence {b,c,b,a}{b,c,b,a}, which is also common to both XX and YY, has length 4. The sequence {b,c,b,a}{b,c,b,a} is an LCS of XX and YY, since there is no common subsequence of length 5 or greater.

Write a program which finds the length of LCS of given two sequences XX and YY. The sequence consists of alphabetical characters.

Input

The input consists of multiple datasets. In the first line, an integer qq which is the number of datasets is given. In the following 2×q2×q lines, each dataset which consists of the two sequences XX and YY are given.

Output

For each dataset, print the length of LCS of XX and YY in a line.

Constraints

  • 1≤q≤1501≤q≤150
  • 1≤1≤ length of XX and YY ≤1,000≤1,000
  • q≤20q≤20 if the dataset includes a sequence whose length is more than 100

Sample Input 1

3
abcbdab
bdcaba
abc
abc
abc
bc

Sample Output 1

4
3
2

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

题意:第一行输入序列的组数n,接下来的2*n行输入两两一对的序列据。输出每一对序列的最长公共子序列(LCS)的长度。

思路:设两个序列分别为X{x1,x2,……xm}和Y{y1,y2……,yn},求X和Y的公共子序列的流程是:

①、若xm和yn相等,则Xm和Yn的LCS就是Xm-1,Yn-1的LCS加上xm;

②、若二者不相等,则Xm和Yn的LCS为Xm-1,Yn的LCS与Xm,Yn-1的LCS中较长的一个;

本题中用数组c[i][j]来代表Xi和Yj的LCS的长度

#include<iostream>
#include<cstring>
using namespace std;

int c[1005][1005];
int n;
int solve(string x,string y){
	int lenx=x.length();
	int leny=y.length();
	int i,j;
	memset(c,0,sizeof(c));
	x=" "+x;    //在xy的第零个字符的位置放空格 
	y=" "+y;
	for(i=1;i<=lenx;i++){
		for(j=1;j<=leny;j++){
			if(x[i]==y[j]){
	            c[i][j]=c[i-1][j-1]+1;
        	}
        	else{
        		c[i][j]=max(c[i-1][j],c[i][j-1]);
         	}
		}
	}
	return c[lenx][leny];	
}
int main(){
	int q,m;
	string x,y;
	cin>>q;
	for(int i=0;i<q;i++){
		cin>>x;
		cin>>y;
		
		cout<<solve(x,y)<<endl;
	}
	
	return 0;
} 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值