Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)web
Problem Description - 題目描述
For example, given "ACGT","ATGC","CGTT" and "CAGT", you can make a sequence in the following way. It is the shortest but may be not the only one.ide
二十一世紀是生物技術日新月異的世紀。咱們知道基因由DNA組成。構建DNA的核苷酸有A(腺嘌呤),C(胞嘧啶),G(鳥嘌呤)和T(胸腺嘧啶)。尋找DNA/蛋白質序列間的最長公共子序列是現代計算分子生物學的基本問題之一。然而這個問題有些許不一樣。給定若干DNA序列,你須要構建一個最短序列使得給定序列都是都是它的子序列。 好比。給定"ACGT","ATGC","CGTT"和"CAGT",你能夠經過以下方式構建一個序列。最短序列不惟一。
The first line is the test case number t. Then t test cases follow. 測試
In each case, the first line is an integer n ( 1<=n<=8 ) represents number of the DNA sequences.ui
The following k lines contain the k sequences, one per line. Assuming that the length of any sequence is between 1 and 5.this
第一行爲測試用例的數量t。隨後t個測試用例。
每一個用例中第一行爲一個整數n ( 1<=n<=8 ) 表示DNA序列的數量。 隨後k行,每行一個序列。假定任意序列長度爲1到5。
Output - 輸出spa
For each test case, print a line containing the length of the shortest sequence that can be made from these sequences.code
對於每一個測試用例,輸出一行可構建序列的最短長度。
Sample Input - 輸入樣例orm
1 4 ACGT ATGC CGTT CAGT
Sample Output - 輸出樣例xml
8
題解blog
IDA* = (暴力DFS + 剪枝)*反反覆覆,因此問題在於怎麼剪枝
若是用剩餘待匹配序列的最大長度來剪枝……下面的數據就有問題(雖然HDU上並無)
1 4 AAAA CCCC GGGG TTTT
而後秉着不會作就百度的原則(逃
橫着看有問題,豎着看?
統計每行ACGT的個數,而後在以此求各個ACGT最大的和,依次剪枝就比上面的方法科學多了……
代碼 C++
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 int maxDeep, n, data[10][10]; 5 int vle(int(&siz)[10][4]) { 6 int i, j, opt, len[4]; 7 memset(len, 0, sizeof len); 8 for (i = 0; i < n; ++i) { 9 for (j = 0; j < 4; ++j) len[j] = std::max(len[j], siz[i][j]); 10 } 11 for (i = opt = 0; i < 4; opt += len[i++]); 12 return opt; 13 } 14 int DFS(int deep, int(&preW)[10], int(&preSiz)[10][4]) { 15 int i = vle(preSiz), j, w[10], siz[10][4], isFid; 16 if (!i) return 1; 17 if (i + deep > maxDeep) return 0; 18 for (i = 0; i < 4; ++i) { 19 memcpy(w, preW, sizeof w); memcpy(siz, preSiz, sizeof siz); 20 for (j = isFid = 0; j < n; ++j) { 21 if (data[j][w[j]] == i) { 22 isFid = ++w[j]; --siz[j][i]; 23 } 24 } 25 if (isFid && DFS(deep + 1, w, siz)) return 1; 26 } 27 return 0; 28 } 29 int main() { 30 int t, i, j, mp[300], w[10], siz[10][4]; 31 mp['A'] = 0; mp['C'] = 1; mp['G'] = 2; mp['T'] = 3; 32 memset(w, 0, sizeof w); 33 char str[10]; 34 scanf("%d", &t); 35 while (t--) { 36 memset(data, 0, sizeof data); memset(siz, 0, sizeof siz); 37 scanf("%d ", &n); 38 for (i = 0; i < n; ++i) { 39 gets(str); 40 for (j = 0; str[j]; ++j) ++siz[i][data[i][j] = mp[str[j]]]; 41 } 42 for (maxDeep = vle(siz); !DFS(0, w, siz); ++maxDeep); 43 printf("%d\n", maxDeep); 44 } 45 return 0; 46 }