题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1560

DNA sequence

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2999    Accepted Submission(s): 1462

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.

 
Input
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.
 
Output
For each test case, print a line containing the length of the shortest sequence that can be made from these sequences.
 
Sample Input
1
4
ACGT
ATGC
CGTT
CAGT
 
Sample Output
8
 
Author
LL
 
Source


题解:

一开始以为是直接用回溯的方法,结果TLE。看了题解是用IDA*(迭代加深搜),其实自己不太了解迭代加深搜为什么比较快,而且什么时候用合适?下面是自己对迭代加深搜的一些浅薄的了解:

1.首先迭代加深搜适合用在:求最少步数(带有BFS的特点)并且不太容易估计搜索深度的问题上,同时兼有了BFS求最少步数和DFS易写、无需多开数组的特点。

2.相对于赤裸裸的回溯,迭代加深搜由于限制了搜索深度,所以也能适当地剪枝。

3.我编不下去了……

代码一:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = +; int n;
char dna[MAXN][MAXN];
int len[MAXN], pos[MAXN];
char s[] = {'A', 'G', 'C', 'T'}; bool dfs(int k, int limit) //k为放了几个, k+1才为当前要放的
{
int maxx = , cnt = ; //maxx为最长剩余的dna片段, cnt为剩余的片段之和(核苷酸链?好怀念啊)
for(int i = ; i<n; i++)
{
cnt += len[i]-pos[i];
maxx = max(maxx, len[i]-pos[i]);
}
if(cnt==) return true; //如果片段都放完,则已得到答案
if(cnt<=limit-k) return true; //剪枝:片段之和小于等于剩余能放数量,肯定能够得到答案
if(maxx>limit-k) return false; //剪枝:最小的估计值都大于剩余能放数量,肯定不能得到答案 int tmp[MAXN];
for(int i = ; i<; i++)
{
memcpy(tmp, pos, sizeof(tmp));
bool flag = false;
for(int j = ; j<n; j++)
if(dna[j][pos[j]]==s[i])
pos[j]++, flag = true; //k+1<=limit:在限制范围内
if(k+<=limit && flag && dfs(k+, limit) )
return true;
memcpy(pos, tmp, sizeof(pos));
}
return false;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int limit = ;
for(int i = ; i<n; i++)
{
scanf("%s",dna[i]);
len[i] = strlen(dna[i]);
limit = max(limit, len[i]);
} ms(pos, );
while(!dfs(, limit))
limit++;
printf("%d\n", limit);
}
}

代码二:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = +; int n;
char dna[MAXN][MAXN];
int len[MAXN], pos[MAXN];
char s[] = {'A', 'G', 'C', 'T'}; bool dfs(int k, int limit) //k为放了几个, k+1才为当前要放的
{
if(k>limit) return false; int maxx = , cnt = ; //maxx为最长剩余的dna片段, cnt为剩余的片段之和(核苷酸链?好怀念啊)
for(int i = ; i<n; i++)
{
cnt += len[i]-pos[i];
maxx = max(maxx, len[i]-pos[i]);
}
if(cnt==) return true; //如果片段都放完,则已得到答案
if(cnt<=limit-k) return true; //剪枝:片段之和小于等于剩余能放数量,肯定能够得到答案
if(maxx>limit-k) return false; //剪枝:最小的估计值都大于剩余能放数量,肯定不能得到答案 int tmp[MAXN];
for(int i = ; i<; i++)
{
memcpy(tmp, pos, sizeof(tmp));
bool flag = false;
for(int j = ; j<n; j++)
if(dna[j][pos[j]]==s[i])
pos[j]++, flag = true; if(flag && dfs(k+, limit) )
return true;
memcpy(pos, tmp, sizeof(pos));
}
return false;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int limit = ;
for(int i = ; i<n; i++)
{
scanf("%s",dna[i]);
len[i] = strlen(dna[i]);
limit = max(limit, len[i]);
} ms(pos, );
while(!dfs(, limit))
limit++;
printf("%d\n", limit);
}
}

HDU1560 DNA sequence —— IDA*算法的更多相关文章

  1. HDU1560 DNA sequence IDA* + 强力剪枝 [kuangbin带你飞]专题二

    题意:给定一些DNA序列,求一个最短序列能够包含所有序列. 思路:记录第i个序列已经被匹配的长度p[i],以及第i序列的原始长度len[i].则有两个剪枝: 剪枝1:直接取最长待匹配长度.1900ms ...

  2. HDU1560 DNA sequence(IDA*)题解

    DNA sequence Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  3. Hdu1560 DNA sequence(IDA*) 2017-01-20 18:53 50人阅读 评论(0) 收藏

    DNA sequence Time Limit : 15000/5000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total ...

  4. HDU1560 DNA sequence

    题目: The twenty-first century is a biology-technology developing century. We know that a gene is made ...

  5. HDU 1560 DNA sequence (IDA* 迭代加深 搜索)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1560 BFS题解:http://www.cnblogs.com/crazyapple/p/321810 ...

  6. HDU 1560 DNA sequence(IDA*)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1560 题目大意:给出n个字符串,让你找一个字符串使得这n个字符串都是它的子串,求最小长度. 解题思路: ...

  7. DNA sequence HDU - 1560(IDA*,迭代加深搜索)

    题目大意:有n个DNA序列,构造一个新的序列,使得这n个DNA序列都是它的子序列,然后输出最小长度. 题解:第一次接触IDA*算法,感觉~~好暴力!!思路:维护一个数组pos[i],表示第i个串该匹配 ...

  8. 【学时总结】 ◆学时·II◆ IDA*算法

    [学时·II] IDA*算法 ■基本策略■ 如果状态数量太多了,优先队列也难以承受:不妨再回头看DFS-- A*算法是BFS的升级,那么IDA*算法是对A*算法的再优化,同时也是对迭代加深搜索(IDF ...

  9. DNA sequence(映射+BFS)

    Problem Description The twenty-first century is a biology-technology developing century. We know tha ...

随机推荐

  1. 中国余数定理 2(codevs 3990)

    题目描述 Description Skytree神犇最近在研究中国博大精深的数学. 这时,Sci蒟蒻前来拜访,于是Skytree给Sci蒟蒻出了一道数学题: 给定n个质数,以及k模这些质数的余数.问: ...

  2. Ubuntu MySQL的安装使用

    删除 mysql sudo apt-get autoremove --purge mysql-server-5.0 sudo apt-get remove mysql-server sudo apt- ...

  3. Mongodb报错:ERROR: child process failed, exited with error number 1

    Mongodb在启动时报错: 2018-10-16T11:18:54.533+0800 I CONTROL [main] Automatically disabling TLS 1.0, to for ...

  4. android Containers控件

    1.RadioGroup 一组单选框容器 2.ListView 3.GridView 4.ExpandableListView 可折叠列表 5.ScrollView 上下滚动条 6.Horizonta ...

  5. Codeforces 515E Drazil and Park (ST表)

    题目链接 Drazil and Park 中文题面 传送门 如果他选择了x和y,那么他消耗的能量为dx + dx + 1 + ... + dy - 1 + 2 * (hx + hy). 把这个式子写成 ...

  6. T1077 多源最短路 codevs

    http://codevs.cn/problem/1077/ 时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 已知n个点(n&l ...

  7. 洛谷——P1057 传球游戏

    P1057 传球游戏 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹 ...

  8. stm32f103c8t6命名

    stm32f103c8t6和stm32f103rbt c8:48脚.64k :rb:64脚.128k.

  9. call lua function from c and called back to c

    Just a simple example: --The  c file: #include <stdio.h> #include "lua.h" #include & ...

  10. [Cypress] install, configure, and script Cypress for JavaScript web applications -- part2

    Use Cypress to test user registration Let’s write a test to fill out our registration form. Because ...