POJ 1699 kmp+枚举

Best Sequence

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 5135   Accepted: 2040

Description

The twenty-first century is a biology-technology developing century. One of the most attractive and challenging tasks is on the gene project, especially on gene sorting program. Recently 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). Given several segments of a gene, you are asked to make a shortest sequence from them. The sequence should use all the segments, and you cannot flip any of the segments.

For example, given ‘TCGG‘, ‘GCAG‘, ‘CCGC‘, ‘GATC‘ and ‘ATCG‘, you
can slide the segments in the following way and get a sequence of length
11. It is the shortest sequence (but may be not the only one).

Input

The
first line is an integer T (1 <= T <= 20), which shows the number
of the cases. Then T test cases follow. The first line of every test
case contains an integer N (1 <= N <= 10), which represents the
number of segments. The following N lines express N segments,
respectively. Assuming that the length of any segment is between 1 and
20.

Output

For each test case, print a line containing the length of the shortest sequence that can be made from these segments.

Sample Input

1
5
TCGG
GCAG
CCGC
GATC
ATCG

Sample Output

11

Source

POJ Monthly--2004.07.18

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 using namespace std;
 7
 8 const int inf=0x3fffffff;
 9 const int maxn=11;
10 char str[maxn][21];
11 int cost[maxn][maxn];
12 int len[maxn];
13 int n,t;
14
15 int cal(char *st1, char *st2)
16 {
17     int len1 = strlen(st1);
18     int len2 = strlen(st2);
19     for (int i = len1 - len2; i < len1; i++)
20     {
21         bool ok = true;
22         for (int j = i; j < len1; j++)
23             if (st1[j] != st2[j - i])
24             {
25                 ok = false;
26                 break;
27             }
28         if (ok)
29             return len2 + i - len1;
30     }
31     return len2;
32 }
33 void work()
34 {
35     for(int i=0;i<n;i++)
36         for(int j=0;j<n;j++)
37     {
38         cost[i][j]=cal(str[i],str[j]);
39     }
40 }
41 int Get_ans()
42 {
43     int next[maxn];int ans=inf,sum;
44     for(int i=0;i<n;i++) next[i]=i;
45     do{
46         sum=len[next[0]];
47         for(int i=0;i<n-1;i++)
48         {
49             sum+=cost[next[i]][next[i+1]];
50         }
51          ans=min(ans,sum);
52         }while(next_permutation(next,next+n));
53         return ans;
54 }
55 int main()
56 {
57     //freopen("in.txt","r",stdin);
58     scanf("%d",&t);
59     while(t--){
60             memset(str,0,sizeof(str));
61             scanf("%d",&n);
62             for(int i=0;i<n;i++)
63             {
64                 scanf("%s",str[i]);
65                 len[i]=strlen(str[i]);
66             }
67             work();
68             int ans=Get_ans();
69             printf("%d\n",ans);
70     }
71     return 0;
72 }
时间: 2024-07-28 13:22:29

POJ 1699 kmp+枚举的相关文章

POJ 1699 Best Sequence (DFS+预处理)

题意:看那张图就一清二楚了吧, N个序列首位相连(相同的序列部分),得到最短的总序列. 题目链接:http://poj.org/problem?id=1699 ~~~~ 思路就是:将N个序列首尾相连能重合的长度求粗来.然后DFS枚举每种首尾相连的情况. #include<cstdio> #include<cstring> #include<algorithm> #define N 22 #define INF 0x7fffffff using namespace std

POJ 1699 Best Sequence(DFS)

題目鏈接 題意 : 將幾個片段如圖所示方法縮成一個序列,求出最短這個序列. 思路 : 其實我也不知道怎麼做.....看網上都用了DP.....但是我不會.....這個DP不錯,還有用KMP+状压DP做的 1 //1699 2 #include <iostream> 3 #include <stdio.h> 4 #include <string.h> 5 #include <string> 6 7 using namespace std; 8 9 string

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 <al

poj 1699 Best Sequence

http://poj.org/problem?id=1699 题意:给你n个长度为L的序列,求包含这几个序列的最短长度. 先预处理每两个序列之间的关系,然后dfs枚举就行. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 500 5 using namespace std; 6 const int inf=1<<30; 7 8 char str[ma

poj 1699 Best Sequence(AC自动机+状压DP)

题目链接:poj 1699 Best Sequence 题目大意:给定N个DNA序列,问说最少多长的字符串包含所有序列. 解题思路:AC自动机+状压DP,先对字符串构造AC自动机,然后在dp[s][i]表示匹配了s,移动到节点i时候的最短步数. #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <iostream> #include &

poj 1873 凸包+枚举

The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6198   Accepted: 1744 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been

Poj 1815 Friendship 枚举+求最小割

给以一个图和两个点S,T,问你拿掉最少多少个点可以使得S和T不连通.输出点数并且输出拿掉的是哪些点,如果有多种方法就输出字典序最小的那个. 这就是一个求最小点割集的问题.无向(有向)图G中,给定源点s和终点t,至少要删去多少个点(具体一点,删哪些点),使得s和t不连通.这个问题就是点连通度,也叫最小点割集. 解法其实理解起来不难,只要把图中的每一个点v拆成v',v''两个点,并建立<v',v''>权为1,这样就把最小点割集转化成求最小割的问题. 对于原图的转化也很简单,对于原来的每条边,转化成

poj 3977 Subset 枚举+二分

首先分成一半2^17和2^18,并且把其中一半变成相反数,然后枚举一半二分查找另一半,在找到的位置前后也找找. 这里用到了二级排序,有很多细节要处理,不多说了. 巨坑的一个地方就是,不能用系统的abs,要自己手写,简直坑死.. #include<cstdio> #include<algorithm> #include<iostream> #include<map> using namespace std; typedef long long ll; stru

poj 1699 Best Sequence(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 &l