IDA*、剪枝、较难搜索、扫描——DNA sequence HDU - 1560
翻译
题意就是给出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的更多相关文章
- DNA sequence HDU - 1560
DNA sequence Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- DNA sequence HDU - 1560(IDA*,迭代加深搜索)
题目大意:有n个DNA序列,构造一个新的序列,使得这n个DNA序列都是它的子序列,然后输出最小长度. 题解:第一次接触IDA*算法,感觉~~好暴力!!思路:维护一个数组pos[i],表示第i个串该匹配 ...
- G - DNA sequence HDU - 1560
题目链接: https://vjudge.net/contest/254151#problem/G AC代码: #include<iostream> #include<cstring ...
- hdu 1560 DNA sequence(迭代加深搜索)
DNA sequence Time Limit : 15000/5000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total ...
- HDU1560 DNA sequence —— IDA*算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1560 DNA sequence Time Limit: 15000/5000 MS (Java/Oth ...
- 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 ...
- HDU1560 DNA sequence(IDA*)题解
DNA sequence Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- hdu 1560 DNA sequence(搜索)
http://acm.hdu.edu.cn/showproblem.php?pid=1560 DNA sequence Time Limit: 15000/5000 MS (Java/Others) ...
- HDU 1560 DNA sequence(DNA序列)
HDU 1560 DNA sequence(DNA序列) Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K ...
随机推荐
- vue开发流程
在安装node.js 测试安装 在cmd 下输入node 如查能正确输出命令提示符,表明安装好node 测试安装npm -v 如果能成功出现版本信息表示安装好npm 安装配置 G码云 或 ...
- python中时间处理标准库DateTime加强版库:pendulum
DateTime 的时区问题 Python的datetime可以处理2种类型的时间,分别为offset-naive和offset-aware.前者是指没有包含时区信息的时间,后者是指包含时区信息的时间 ...
- 个人作业——CVPR顶会论文爬取
main.py #保存单个界面数据 def getInfo(url): # url='https://openaccess.thecvf.com/WACV2021' header={ 'User-Ag ...
- Mysql实现无插入有更新(不知主键的情况下)
网上很多资料说有两种方式 (必须现有唯一键) 1.INSERT 中ON DUPLICATE KEY UPDATE的使用 2.REPLACE的使用 通过可以得出结果: 如果a和b字段 能决定唯一 例子: ...
- Nginx系列(10)- Nginx配置文件详解
nginx文件结构 ... #全局块 events { #events块 ... } http #http块 { ... #http全局块 server #server块 { ... #server全 ...
- Django边学边记—新手Django建项目各流程细节
一.准备虚拟环境 1)安装 virtualenv pip install virtualenv 2)virtualenvwrapper pip install virtualenvwrapper-wi ...
- linux帐户安全管理与技巧
实验环境 CentosOS5.6试验台. 任务一:建立与删除普通用户账户,管理组 1)创建一个新用户user1 useradd user1 查看用户是否创建成功 2)创建一个新组group1 grou ...
- requests接口测试-requests的安装
requests接口测试-requests的安装 安装常见问题 提示连接不上,443问题 一般是因为浏览器设置了代理,关闭代理. 网络加载慢,设置国内镜像地址 1.pip安装 2.pycharm安装 ...
- requests接口自动化-assert断言
断言,自动判断接口返回的结果与预期结果是否一致 from common.get_mysql import * def test_assert(): a=0 b=1 # assert a,'断言失败打印 ...
- layui左右移动tab标签模版
{% load staticfiles %} <!DOCTYPE html> <html> <head> <meta charset="utf-8& ...