最長公共子串行
problem description
從乙個給定的串中刪去(不一定連續地刪去)0個或0個以上的字元,剩下地字元按原來順序組成的串。例如:
「 」,「a」,「xb」,「aaa」,「bbb」,「xabb」,「xaaabbb」都是串「xaaabbb」的子串行。(例子中的串不包含引號。)
程式設計求n個非空串的最長公共子串行的長度。限制:2<=n<=100;n個串中的字元只會是數字0,1,…,9或小寫英文本母a,b,…,z;每個串非空且最多含100個字元;n個串的長度的乘積不會超過30000。
input
檔案第1行是乙個整數t,表示測試資料的個數(1<=t<=10)。接下來有t組測試資料。各組測試資料的第1行是乙個整數ni,表示第i組資料中串的個數。各組測試資料的第2到n+1行中,每行乙個串,串中不會有空格,但行首和行末可能有空格,這些空格當然不算作串的一部分。
output
輸出t行,每行乙個數,第i行的數表示第i組測試資料中ni個非空串的最長公共子串行的長度。
sample input13
abbc
cdsample output
0解題思路
題目中有一句話:n個串的長度的乘積不會超過30000,這個地方告訴了我們資料的規模並且還強調了n個串長度的乘積,這裡就要提一下,在求兩字串行的最長公共字元子串行這個問題中,我們為了方便理解,會畫乙個m * n的**(m代表字串x的長度,n代表字串y的長度,x,y為任意兩字串行)來觀察公共字元個數,兩字串行的最長公共字元子串行問題還可以看成二維公共子串行問題,因為解題的時候我們會建立乙個二維陣列。
該題可以看成乙個多維字元求最長公共子串行,但是題目說:n個子符串的乘積不會超過30000。這裡我們就可以把這道多維問題轉化為乙個一維問題,參照求兩字串行的最長公共字元子串行問題把本該建立的多維**給轉化為一維陣列。每乙個index都對應著唯一的情況,即:多維字串的長度為x1,x2,x3……xi時是否有公共字元。
具體思路如下:
建立乙個二維字元陣列儲存字元,建立乙個一維陣列len來儲存每乙個字元陣列的長度,一維陣列l來儲存多維字元陣列長度的動態變化,用於求index(這部分請結合下面的**利於理解),我們從每乙個字元陣列的末尾開始匹配,若都相等則把每乙個多維陣列長度l減一(所以我稱它為動態長度陣列),所以最長長度ret = dp(l) + 1;若只要有乙個不同,則開始列舉每一種情況,詳細請看**:
#include
using
namespace std;
char a[
110]
[110];
int dp[
30010];
int len[
110]
;int n;
intdp
(int
*x)else
} dp[index]
=ret;
return ret;
}int
main()
memset
(dp,-1
,sizeof
(dp));
printf
("%d\n",dp
(l));}
return0;
}
最長公共子串行問題 動態規劃sdut
最長公共子串行問題 description 給定兩個序列 x 和 y 找出x和y的最長公共子串行。input 輸入資料有多組,每組有兩行 每行為乙個長度不超過500的字串 輸入全是大寫英文本母 a,z 表示序列x和y。output 每組輸出一行,表示所求得的最長公共子串行的長度,若不存在公共子串行,...
SDUT 最長公共子串行長度 動態規劃
time limit 1000 ms memory limit 65536 kib submit statistic problem description 給定兩個序列x input 輸入資料有多組,每組有兩行 每行為乙個長度不超過500的字串 輸入全是大寫英文本母 a,z 表示序列x和y。out...
動態規劃 最長公共子串行
問題描述 我們稱序列z z1,z2,zk 是序列x x1,x2,xm 的子串行當且僅當存在嚴格上公升的序列 i1,i2,ik 使得對j 1,2,k,有xij zj。比如z a,b,f,c 是x a,b,c,f,b,c 的子串行。現在給出兩個序列x和y,你的任務是找到x和y的最大公共子串行,也就是說要...