問題 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;
}