万恶之源

翻译

题意就是给出N个DNA序列,要求出一个包含这n个序列的最短序列是多长

这是一道搜索题,为什么呢?从样例可以感受到,我们应该从左往右“扫描”,从n个DNA序列中取出某个特定的字母,直到n个序列都被取空。题目便是要求这个“取出”次数的最小值。而我们每次都选择A,T,C,G中的其中一个取出,这样便形成了一个不断以4个叶子延申的搜索树了。(请自行脑补)(当然实际必须要剪掉)

IDA*

这题很适合用IDA*,随着深度不断增加,第一个访问到的答案一定是最优解。而庞大的数据,也需要我们设计一个评估函数。

剪枝

我们使用评估函数来进行剪枝。很自然可以想到,我们用已经处理完的长度,加上估计还需要的长度,它如果大于给定的长度,那么这种方法就是不可行的,那么我们就可以退出。

具体而言,有两种方法可以进行待处理长度的预测。一种是计算当前各序列未就位的序列的最大长度;另外一种是统计各个字母在所有序列的未就位的序列中的最大数量之和

实践表明,后者是更优的。

布尔型的函数

对于返回值的理解,首先这个dfs函数是布尔型的,剪枝即判错,其它情况下,返回值则是下一层的子函数的返回值,下一层的返回值又是由下下一层的返回值决定的……不断这样递归下去,当找到正确答案时那就会不断返回true直至给第一个母函数啦。具体而言,首先在dfs的开头要剪枝,然后用一个循环对不同操作再次进行搜索,这若干个操作之中若有一个为真,那么这个函数就会返回真;只有当他们全部返回假,当前这个函数才会返回假。

过程中的重大错误

  • 把int类型的eva函数写成了bool,导致所有非0的数都变成了 1
  • 忘记给递归函数的某些路径设置返回值,导致函数返回异常值,明明是bool类型的函数,居然返回了4。。。影响了后续的判断(我当时还忽略了编译器的友情提醒:不是所有的路径都返回值...)
  • 当有多次操作时,要注意状态的初始化,包括各种数组与一些最大最小值等任何一个过程中需要的变量都要检查。

代码

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int T, n;//T是总问题数,n是每个问题里面有多少个DNA序列 struct node {
int len;
string str;
}dna[10];
char part[5] = { 'A', 'T', 'G', 'C' };//扫描的顺序,不一定是这个,只是说按我这个顺序来进行操作然后接着dfs
int pos[10] = { 0 };//记录第i个字符串扫描到了第几位
int eva() {
int maxn = -1;
for (int i = 0; i < n; i++) {
maxn = max(maxn, dna[i].len - pos[i]);
}
return maxn;
}
int eva2() {//比第eva快了二十倍
int ans = 0;
int cnt[4] = { 0 };
int maxn[4] = { 0 };
for (int i = 0; i < n; i++) {
int a = 0, b = 0, c = 0, d = 0;
for (unsigned int j = pos[i]; j < dna[i].str.length(); j++) {
if (dna[i].str[j] == 'A') cnt[0]++;
if (dna[i].str[j] == 'T') cnt[1]++;
if (dna[i].str[j] == 'G') cnt[2]++;
if (dna[i].str[j] == 'C') cnt[3]++;
}
for (int k = 0; k < 4; k++) {
maxn[k] = max(maxn[k], cnt[k]);
cnt[k] = 0;
}
}
for (auto i : maxn)
ans += i;
return ans;
}
bool IDA(int now, int dep) {
int e = eva2();
//printf("e is %d, now is %d, dep is %d\n", e, now, dep); if (now > dep) return false;//最后一个dfs返回false的条件
if (now + e > dep) return false;//剪枝
if (e == 0) return true;////最后一个dfs返回true的条件 //这函数应该是bool类型的吗?这样只有某一个子函数会为真吧?那最开始的那个呢?---不断递归,不断返回
//整个函数返回true的条件是什么,应该不是放在开头吧---开头的可以保证最后一个dfs返回真,结尾的可以保证过程中的dfs返回真(false同理) int tep[10] = { 0 };
memcpy(tep, pos, sizeof(tep));
for (int i = 0; i < 4; i++) {
int flag = 0;
for (int j = 0; j < n; j++) {
// printf("i is %d, j is %d\n", i, j);
if (dna[j].str[pos[j]] == part[i]) {
pos[j]++;
flag = 1;
}
}
/*
for (int j = 0; j < n && flag; j++)
printf("pos[%d] is %d\n", j, pos[j]);
cout << endl;
*/
if (flag) {
if (IDA(now + 1, dep))
return true;
}
memcpy(pos, tep, sizeof(pos));
}
return false;//没有这一句递归就无法进行,为什么?!
} int main(void) {
cin >> T;
while (T--) {
cin >> n;
memset(pos, 0, sizeof(pos)); int maxn = 1;
for (int i = 0; i < n; i++) {
cin >> dna[i].str;
dna[i].len = dna[i].str.length();
maxn = max(dna[i].len, maxn);
}
int dep;
for (dep = maxn;; dep++) {
memset(pos, 0, sizeof(pos));
if (IDA(0, dep)) break;
}
cout << dep << endl;
for (int i = 0; i < n; i++) {
dna[i].str.clear();
dna[i].len = 0;
}
} return 0;
}

IDA*、剪枝、较难搜索、扫描——DNA sequence HDU - 1560的更多相关文章

  1. DNA sequence HDU - 1560

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

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

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

  3. G - DNA sequence HDU - 1560

    题目链接: https://vjudge.net/contest/254151#problem/G AC代码: #include<iostream> #include<cstring ...

  4. hdu 1560 DNA sequence(迭代加深搜索)

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

  5. HDU1560 DNA sequence —— IDA*算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1560 DNA sequence Time Limit: 15000/5000 MS (Java/Oth ...

  6. 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 ...

  7. HDU1560 DNA sequence(IDA*)题解

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

  8. hdu 1560 DNA sequence(搜索)

    http://acm.hdu.edu.cn/showproblem.php?pid=1560 DNA sequence Time Limit: 15000/5000 MS (Java/Others)  ...

  9. HDU 1560 DNA sequence(DNA序列)

    HDU 1560 DNA sequence(DNA序列) Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K  ...

随机推荐

  1. 【Nginx】Linux常用命令------启动、停止、重启

    启动 启动代码格式:nginx安装目录地址 -c nginx配置文件地址 例如: [root@LinuxServer sbin]# /usr/local/nginx/sbin/nginx -c /us ...

  2. 加入Erlang社区-指引

    国内暂且没有发现较活跃.人气较高的论坛或者社区,偶然发现Erlang官网的Community页面描述了一个Slack交流平台,里面有众多异国他乡的大佬,感兴趣的.有技术疑问的都可以加入看看. 加入教程 ...

  3. 集合Collection ----List集合

    Collection集合体系的特点: set系列集合:添加的元素是 无序,不重复,无索引的 ----HashSet: 无序,不重复,无索引 ----LinkedHashSet: 有序,不重复,无索引 ...

  4. DP之背包经典三例

    0/1背包 HDU2602 01背包(ZeroOnePack): 有N件物品和一个容量为V的背包,每种物品均只有一件.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大 ...

  5. PTA——c++类与对象

    对于给定的一个字符串,统计其中数字字符出现的次数. 类和函数接口定义: 设计一个类Solution,其中包含一个成员函数count_digits,其功能是统计传入的string类型参数中数字字符的个数 ...

  6. Java Web实现登录验证码(Servlet+jsp)

    1.生成验证码图片(Servlet) import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import j ...

  7. Elasticsearch(ES)集群的搭建

    1. 概述 Elasticsearch(ES)集群支持分片和副本,能够很容易的实现负载均衡.扩容.容灾.高可用. 今天我们就来聊一下,Elasticsearch(ES)集群是如何搭建的. 2. 场景介 ...

  8. (转载https://segmentfault.com/a/1190000016313947)了解RestFul Api架构风格设计

    最近几年REST API越来越流行,特别是随着微服务的概念被广泛接受和应用,很多Web Service都使用了REST API. REST是HTTP规范主要编写者之一的Roy Fielding提出的, ...

  9. 获取系统版本,判断是windows还是Linux

    package com.foresee.zxpt.common.utils; import java.util.Properties; /** * 获取系统版本 * @author GZ * */ p ...

  10. no rxtxSerial in java.library.path

    java开发过程中,遇到no rxtxSerial in java.library.path问题,是由于缺少一个dll文件导致. 在jre/bin下添加rxtxSerial.dll 文件 win10环 ...