标签:dfs
http://poj.org/problem?id=1699
题意:给出n个只含A,C,G,T的字符串,要求能把这n个字符串组合起来的最短长度。
思路:预处理一下,a[i][j]表示将第j个字符串连接到第i个字符串后面增加的长度,那么我们需要找出这样一个序列1,2....n满足a[1][2] + a[2][3] + ...+a[n-1][n]的最小值。DFS就OK了,任选一个字符串作为起点进行dfs,求出所有的情况后得到最小的长度。
#include <stdio.h> #include <iostream> #include <algorithm> #include <set> #include <map> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #define LL long long #define _LL __int64 #define eps 1e-8 using namespace std; const int INF = 0x3f3f3f3f; char s[12][22]; int n; int a[12][12]; int vis[12]; int ans; //维护最短长度 int cal(char s1[], char s2[]) { int len1 = strlen(s1); int len2 = strlen(s2); int i,j,t; int flag; if(strcmp(s1,s2) == 0) return 0; for(int k = 1; k <= len2; k++) { t = len2 - k; i = len1 - t; j = 0; flag = 1; while(i < len1 && j < t) { if(s1[i] == s2[j]) { i++; j++; } else { flag = 0; break; } } if(flag == 1) return k; } } void solve() { for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(i == j) continue; a[i][j] = cal(s[i],s[j]); } } } void dfs(int x, int step, int sum) { if(step > ans) //剪枝,当step > ans时没不要继续递归了、 return; if(sum == n) { ans = min(ans,step); return; } for(int i = 0; i < n; i++) { if(!vis[i]) { vis[i] = 1; dfs(i,step + a[x][i], sum+1); vis[i] = 0; } } } int main() { int test; scanf("%d",&test); while(test--) { scanf("%d",&n); ans = 0; for(int i = 0; i < n; i++) { scanf("%s",s[i]); ans += strlen(s[i]); } solve(); //预处理求出a[][] memset(vis,0,sizeof(vis)); for(int i = 0; i < n; i++) { vis[i] = 1; dfs(i,strlen(s[i]),1); vis[i] = 0; } printf("%d\n",ans); } return 0; }
poj 1699 Best Sequence(dfs),布布扣,bubuko.com
标签:dfs
原文地址:http://blog.csdn.net/u013081425/article/details/28729293