首页 > 代码库 > poj 1699 Best Sequence (搜索技巧 剪枝 dfs)
poj 1699 Best Sequence (搜索技巧 剪枝 dfs)
题目链接
题意:给出几个基因片段,要求你将它们排列成一个最短的序列,序列中使用了所有的基因片段,而且不能翻转基因。
分析:先计算出add数组,再dfs枚举。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <cstdio> 6 #include <vector> 7 #include <algorithm> 8 #define LL long long 9 using namespace std;10 const int maxn = 20+10;11 const int INF = 1<<28;12 int n, len[maxn], add[maxn][maxn], ans;13 bool vis[maxn];14 char s[maxn][maxn];15 16 void cal(int a, int b, int lena, int lenb) //add计算串a在串b,前面增加的字符个数。17 {18 int i, j, k, f, x;19 for(i = 0; i < lena; i++)20 {21 f = 0;22 for(j = 0, k = i; j < lenb && k < lena; j++, k++)23 {24 if(s[a][k] == s[b][j]) continue;25 else { f = 1; break; }26 }27 if(f == 0) break;28 }29 x = lena - i;30 add[a][b] = lenb - x;31 if(add[a][b]<0) add[a][b] = 0;32 }33 void dfs(int pre, int sum, int lenth) //分别代表之前的串,和串的总数,总串的长度。34 {35 if(lenth >= ans) return;36 if(sum == n)37 {38 if(lenth < ans) ans = lenth;39 return;40 }41 for(int i = 0; i < n; i++)42 {43 if(!vis[i])44 {45 vis[i] = true;46 if(add[pre][i]==0) //一定要注意这是存在包含串,如abcdabc 包含 dab47 //串a包含串b,等价于从a到b的边等于0,那么这时,状态在转移时,在原本48 //是以串a结尾的状态加入串b,此时目标状态仍然是以串a结尾,这里需要注意。49 dfs(pre, sum+1, lenth+add[pre][i]);50 else51 dfs(i, sum+1, lenth+add[pre][i]);52 vis[i] = false;53 }54 }55 }56 int main()57 {58 int t, i, j;59 scanf("%d", &t);60 while(t--)61 {62 ans = INF;63 memset(add, 0, sizeof(add));64 memset(vis, false, sizeof(vis));65 scanf("%d", &n);66 for(i = 0; i < n; i++)67 {68 scanf("%s", s[i]);69 len[i] = strlen(s[i]);70 }71 for(i = 0; i < n; i++)72 for(j = 0; j < n; j++)73 cal(i, j, len[i], len[j]);74 for(i = 0; i < n; i++)75 {76 vis[i] = true;77 dfs(i, 1, len[i]);78 vis[i] = false;79 }80 printf("%d\n", ans);81 }82 return 0;83 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。