Longest Common Subsequence

Longest Common Subsequence

最長共通部分列

最長共通部分列問題 (Longest Common Subsequence problem: LCS)は、2つの与えられた列 X={x1,x2,...,xm} Y={y1,y2,...,yn} の最長共通部分列を求める問題です。

ある列 Z X Y 両方の部分列であるとき、Z X Y の共通部分列と言います。例えば、 X={a,b,c,b,d,a,b} , Y={b,d,c,a,b,a} とすると、列 {b,c,a} X Y の共通部分列です。一方、列 {b,c,a} X Y の最長共通部分列ではありません。なぜなら、その長さは 3 であり、長さ 4 の共通部分列 {b,c,b,a} が存在するからです。長さが 5 以上の共通部分列が存在しないので、列 {b,c,b,a} X Y の最長共通部分列の1つです。

与えられた2つの文字列 X Yに対して、最長共通部分列 Z の長さを出力するプログラムを作成してください。与えられる文字列は英文字のみで構成されています。
入力

複数のデータセットが与えられます。最初の行にデータセットの数 q が与えられます。続く 2×q 行にデータセットが与えられます。各データセットでは2つの文字列 X , Y がそれぞれ1行に与えられます。

出力

各データセットについて X , Y の最長共通部分列 Z の長さを1行に出力してください。

制約

1q150
1X,Y1,000
X または Y の長さが 100 を超えるデータセットが含まれる場合、 q は 20 以下である。

入力例 1

3
abcbdab
bdcaba
abc
abc
abc
bc

出力例 1

4
3
2

参考文献

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

解题思路:
本题是一个裸的LCS,动态转移方程如下

s1[i1]==s2[j1] dp[i][j]=dp[i1][j1]+1
否则 dp[i][j]=max(dp[i1][j],dp[i][j1])
i和j表示序列一的前i个字符和序列二的前j个字符的最长公共子序列的长度为dp[i][j]

代码如下:

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

const int maxn = 1050;

char s1[maxn],s2[maxn];
int f[maxn][maxn];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s%s",s1,s2);
        int len1 = strlen(s1);
        int len2 = strlen(s2);
        memset(f,0,sizeof(f));
        for(int i = 0;i <= len1; i++)
        {
            for(int j = 0;j <= len2; j++)
            {
                if(i == 0 || j == 0)f[i][j] = 0;
                else
                {
                    if(s1[i-1] == s2[j-1])f[i][j] = f[i-1][j-1] + 1;
                    else f[i][j] = max(f[i-1][j],f[i][j-1]);
                }
            }
        }
        printf("%d\n",f[len1][len2]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值