HDU 1560 DNA Secence(IDA*)

题意

  输入一些只包含A、C、G、T的字符串,找出一条最短的字符串,使得输入都是该字符串的子序列(不用连续),输出找到的字符串的长度

思路

  考虑类似trie树这样的结构,从根开始,所有字符串沿着一条路下来能按顺序匹配上自身所有字符,该条路就是最终要找的字符串

  所以从跟开始向下搜索,没个节点处也要保存到该节点时各个字符串的状态。

  一开始尝试直接用BFS,但是随着层数增多,队列内的节点也越来越多,再加上每个节点入队时保存了该点字符串的信息,和预料的一样,mle了

  所以考虑尽快处理一条路上的数据处理掉,减小空间占用,考虑使用DFS搜索,但是要控制每次递归的层数,不断加深搜索层数,即迭代加深搜索(IDA*)

代码

/*
	HDU 1560 
	IDA*
*/
#include<vector>
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#define max(x,y) x>y?x:y
using namespace std;
int k, n, ans;
vector<string> gens;
string gen;
string dna = "ACGT";
//当前层数,最大层数,各个字符串匹配到的位置
void dfs(int colum, int maxcolum, vector<int>& vi)
{
    //当前层数已经大于期望最深层数,剪枝
	if (colum > maxcolum) return;
    //当前所有字符串剩下最长的长度
	int tmp = 0;   
	for (int i = 0; i < n; i++)
	{
		tmp = max(tmp, gens[i].length() - vi[i]);
	}
	if (tmp == 0)
	{
		ans = colum;
		return;
	}
	if (colum + tmp > maxcolum) return;
    //每一层都是A、C、G、T四个字符,依次判断每个字符串能否匹配上
	for (int i = 0; i < 4; i++)
	{
		bool flag = false;
		vector<int> pos(vi);
		for (int j = 0; j < n; j++)
		{
			if (pos[j] >= gens[j].length()) continue;
			if (dna[i] == gens[j][pos[j]])
			{
				pos[j]++;
				flag = true;
			}
		}
		if (flag)
		{
			dfs(colum + 1, maxcolum, pos);			
			if (ans != 0) return;
		}
	}
}
int main()
{
	cin.sync_with_stdio(false);
	cin >> k;
	while (k--)
	{
		cin >> n;
		int depth = 0;
		ans = 0;
		gens.clear();
		for (int i = 0; i < n; i++)
		{
			cin >> gen;
			depth = max(depth, gen.length());
			gens.push_back(gen);
		}
		vector<int> pos(n, 0);
		for (;; depth++)
		{
			dfs(0, depth, pos);
			if (ans != 0) break;
		}
		cout << ans << endl;
	}
}

第一次写完mle后参考了大佬们的题解写的,所以代码和大佬的题解非常相似

参考资料

DFS深度优先搜索(4)–hdu1560(进阶题)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值