题目链接: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. LVM 类型的 Storage Pool

    LVM 类型的 Storage Pool 不仅一个文件可以分配给客户机作为虚拟磁盘,宿主机上 VG 中的 LV 也可以作为虚拟磁盘分配给虚拟机使用. 不过,LV 由于没有磁盘的 MBR 引导记录,不能 ...

  2. GIL锁、死锁、递归锁、定时器

    GIL (Global Interpreter Lock) 锁 '''定义:In CPython, the global interpreter lock, or GIL, is a mutex th ...

  3. 洛谷 P1503鬼子进村

    题目背景 小卡正在新家的客厅中看电视.电视里正在播放放了千八百次依旧重播的<亮剑>,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战. 题目描述 描述 县城里 ...

  4. CodeWar---将字符串转换为驼峰命名

    Convert string to camel case 将字符串转换为驼峰命名 自己的解法 将不是字母和数字的字符用.取代,再根据点划分数组.将下标不为0的数组首字符大写,剩下全部小写 static ...

  5. WebGIS开发之用openlayers加载离线百度地图

    因为项目需要,只有内网环境,没有外网环境,所以需要下载地图瓦片. 一.下载瓦片地图 这个可以自行在网上找一些地图瓦片下载器,下好的瓦片地图是分级的.大概如图这种类型. 二.在地图上显示标记 首先使用o ...

  6. 关于one-hot encoding思考

    Many learning algorithms either learn a single weight per feature, or they use distances between sam ...

  7. SolidEdge 工程图中如何绘制中断视图

    右击长条形的视图,点击新增断裂线,然后绘制两个断点   点击完成之后效果如下图所示   如果要修改断裂视图的样式,则选中这个视图,在左键单击,然后点击这个按钮取消显示断裂视图   然后左键单击断裂视图 ...

  8. sort-list——链表、快慢指针找中间、归并排序

    Sort a linked list in O(n log n) time using constant space complexity. 链表,快慢指针找中点,归并排序. 注意判断条件fast-& ...

  9. LOCAL_CFLAGS参数说明

    1.-Wall 是打开警告开关 2.-O 代表默认优化,可选:-O0不优化,-O1低级优化,-O2中级优化,-O3高级优化,-Os代码空间优化 3.-g 是生成调试信息,生成的可执行文件具有和源代码关 ...

  10. push代码到github时,每次都要输入用户名和密码的问题

    问题原由 我在Github上 建立了一个小项目TauStreamingServer,可是在每次push代码 的时候,都要求输入用户名和密码,很是麻烦. 如何才能避免每次都输入用户名和密码呢? 解决办法 ...