HDU 1583 DNA Assembly(暴力模擬)

DNA Assembly

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 213 Accepted Submission(s): 88


Problem Description
Farmer John has performed DNA sequencing on his prize milk-producing cow, Bessie DNA sequences are ordered lists (strings) containing the letters 'A', 'C', 'G', and 'T'.

As is usual for DNA sequencing, the results are a set of strings that are sequenced fragments of DNA, not entire DNA strings. A pair of strings like 'GATTA' and 'TACA' most probably represent the string 'GATTACA' as the overlapping characters are merged, since they were probably duplicated in the sequencing process.

Merging a pair of strings requires finding the greatest overlap between the two and then eliminating it as the two strings are concatenated together. Overlaps are between the end of one string and beginning of another string, NOT IN THE MIDDLE OF A STRING.

By way of example, the strings 'GATTACA' and 'TTACA' overlap completely. On the other hand, the strings 'GATTACA' and 'TTA' have no overlap at all, since the matching characters of one appear in the middle of the other, not at one end or the other. Here are some examples of merging strings, including those with no overlap:



GATTA + TACA -> GATTACA
TACA + GATTA -> TACAGATTA
TACA + ACA -> TACA
TAC + TACA -> TACA
ATAC + TACA -> ATACA
TACA + ACAT -> TACAT
Given a set of N (2 <= N <= 7) DNA sequences all of whose lengths are in the range 1..7, find and print length of the shortest possible sequence obtainable by repeatedly merging all N strings using the procedure described above. All strings must be merged into the resulting sequence.

Input
The input consists of multiple test cases.
Each test case :
Line 1: A single integer N

Lines 2..N+1: Each line contains a single DNA subsequence
End of file.

Output
For each pair of input output the length of the shortest possible string obtained by merging the subsequences. It is always possible – and required – to merge all the input strings to obtain this string.

Sample Input
4 GATTA TAGG ATCGA CGCAT

Sample Output
13
Hint
Hint
Explanation of the sample: Such string is "CGCATCGATTAGG".

Source

/*
題目意思:讓你拼接字符串,使長度最少; 
思路:
法一:由於N好小,直接暴力模擬,對N個字符串進行全排列,若可以,則算出結果長度;
法二:圖論:
第i個字符串作爲點i,枚舉i到其他點是否可以拼接,若可以,則有向邊,權值爲公共長度
標記入度,和鄰接表vector
對入度爲0的作爲起點枚舉,回朔標記點是否訪問過,累加權值最大sum
所有字符串的長度-最大公共長度=結果 
*/
/*用的法1  不知爲何wa?  知道的求告知*/
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string s[10];
int a[10];
int map[10][10]; 
int n,sum,re;
inline int check(int x,int y){
	int i,j;
     for(i=0;i<s[x].length();i++){
     	for(j=0;j<s[y].length()&&i+j<s[x].length();j++){
     		 if(s[x][i+j]!=s[y][j])
     		    break;
		 }	
		 	if(i+j==s[x].length()) //前者必須到結尾完 
		 	  return j;
	 }
	 return -1;
}
int main()
{  
    while(cin>>n){
    	sum=0;  //字符串總長 
    	re=-99999999;   //最長公共部分 
    	for(int i=0;i<n;i++){
    		cin>>s[i];
    		sum+=s[i].length();
    		a[i]=i;
		}
		for(int i=0;i<n;i++){   //一點到其他點的公共長度; 
			for(int j=0;j<n;j++){
				if(j==i){
					map[i][j]=-1;
					continue;
				}				 
				map[i][j]=check(i,j);			
			}		
		}		
		/*	for(int i=0;i<n;i++){   
			for(int j=0;j<n;j++)
				cout<<map[i][j]<<" ";
			cout<<endl;*/		
		do{
		    bool ok=1;
		    int tmp=0;
		    for(int i=0;i<n-1;i++){
		    	if(map[a[i]][a[i+1]]==-1)
		    	  {
		    	  	 ok=0;
		    	  	 break;
				  }	
				 else{
				 	tmp+=map[a[i]][a[i+1]];
				 }	 
			}
			if(ok){
				if(re<tmp)
				  re=tmp;
			}
		}while(next_permutation(a,a+n));
		cout<<sum-re<<endl; 
	}
	return 0;
}



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