HDU 1560 DNA sequence(DNA序列)
HDU 1560 DNA sequence(DNA序列)
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description - 題目描述 The twenty-first century is a biology-technology developing century. We know that a gene is made of DNA. The nucleotide bases from which DNA is built are A(adenine), C(cytosine), G(guanine), and T(thymine). Finding the longest common subsequence between DNA/Protein sequences is one of the basic problems in modern computational molecular biology. But this problem is a little different. Given several DNA sequences, you are asked to make a shortest sequence from them so that each of the given sequence is the subsequence of it.
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.
二十一世紀是生物技術突飛猛進的世紀。我們知道基因由DNA組成。構建DNA的核苷酸有A(腺嘌呤),C(胞嘧啶),G(鳥嘌呤)和T(胸腺嘧啶)。尋找DNA/蛋白質序列間的最長公共子序列是現代計算分子生物學的基本問題之一。然而這個問題有些許不同。給定若幹DNA序列,你需要構建一個最短序列使得給定序列都是都是它的子序列。 比如。給定CN Input - 輸入"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.
The following k lines contain the k sequences, one per line. Assuming that the length of any sequence is between 1 and 5.
第一行為測試用例的數量t。隨後t個測試用例。
每個用例中第一行為一個整數n ( 1<=n<=8 ) 表示DNA序列的數量。
隨後k行,每行一個序列。假定任意序列長度為1到5。
CN
Output - 輸出
For each test case, print a line containing the length of the shortest sequence that can be made from these sequences.
對於每個測試用例,輸出一行可構建序列的最短長度。CN
Sample Input - 輸入樣例
1 4 ACGT ATGC CGTT CAGT
Sample Output - 輸出樣例
8
題解
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 }
HDU 1560 DNA sequence(DNA序列)