【算法筆記第11.4節-動態規劃】問題 A: 最長公共子序列

問題 A: 最長公共子序列

時間限制: 1 Sec  內存限制: 32 MB
提交: 335  解決: 185
[提交][狀態][討論版][命題人:外部導入]

題目描述

給你一個序列X和另一個序列Z,當Z中的所有元素都在X中存在,並且在X中的下標順序是嚴格遞增的,那麼就把Z叫做X的子序列。
例如:Z=<a,b,f,c>是序列X=<a,b,c,f,b,c>的一個子序列,Z中的元素在X中的下標序列爲<1,2,4,6>。
現給你兩個序列X和Y,請問它們的最長公共子序列的長度是多少?

輸入

輸入包含多組測試數據。每組輸入佔一行,爲兩個字符串,由若干個空格分隔。每個字符串的長度不超過100。

輸出

對於每組輸入,輸出兩個字符串的最長公共子序列的長度。

樣例輸入

abcfbc abfcab
programming contest 
abcd mnp

樣例輸出

4
2
0

從書上可以知道:

dp[i][j] : 字符串a的i位和字符串b的j號位之前的最長公共子序列長度

狀態轉移方程:

dp[i][j] =    dp[i-1][j-1] + 1,   a[i]==b[j]

                 max{dp[i-1][j], dp[i][j-1], a[i]!=b[j]

邊界:dp[i][0] = dp[0][j] = 0 (0<=i<=n, 0<=j<=m)

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char a[101], b[101];
int dp[101][101];
int main()
{
    int n;
    while(scanf("%s %s",a+1, b+1)!=EOF)//從下標爲1開始讀入
    {
        int lena = strlen(a+1);//由於讀入時下標從1開始,因此讀取長度也從+1開始
        int lenb = strlen(b+1);
        //邊界
        for(int i=0; i<=lena; i++)
            dp[i][0] = 0;
        for(int j=0; j<=lenb; j++)
            dp[0][j] = 0;
        //狀態轉移方程

        for(int i=1; i<=lena; i++)
            for(int j=1; j<=lenb; j++)
        {
            if(a[i]==b[j])
                dp[i][j] = dp[i-1][j-1] + 1;
            else
                dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
        }
        //dp[lena][lenb]
        printf("%d\n", dp[lena][lenb]);
    }
    return 0;
}

              

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章