您的位置:首页 > 其它

[IDDFS] HDU 1560

2017-11-12 17:44 162 查看
给出N个DNA序列,要求出一个包含这n个序列的最短序列是多长

因为是求最小,所以用迭代加深,直接防止深搜搜索得过头

迭代加深就是逐渐增加搜索的范围。

最初我们只搜索maxd的范围,当maxd内没有我们需要的答案时,我们将maxd+1,而后继续搜索。

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

inline int max ( int a, int b ) { return a > b ? a : b; }

int n; //字符串个数
int ans; //最终结果
int depth; //最大搜索深度

char str[ 10 ][ 10 ];

char DNA[ 4 ] = {'A', 'T', 'C', 'G'};

// cnt: 当前已经有了多长的字符串
// len[]: n个字符串已经搜素到了的位置
void dfs ( int cnt, int len[] ) {

if ( cnt > depth )
return;

//求每个串还剩下多少
int remain = 0;
for ( int i = 0; i < n; ++i )
remain = max ( strlen ( str[ i ] ) - len[ i ], remain );

if ( remain == 0 ) {
ans = cnt;
return;
}

if ( remain + cnt > depth ) //该限定深度搜索不到
return;

for ( int i = 0; i < 4; ++i ) {
int pos[ 10 ];
int flag = 0;

//匹配到至少一个就能往下搜索
for ( int j = 0; j < n; ++j ) {
//匹配到的len+1
if ( str[ j ][ len[ j ] ] == DNA[ i ] )
flag = 1, pos[ j ] = len[ j ] + 1;
//没匹配到的len不变
else
pos[ j ] = len[ j ];
}

if ( flag )
dfs ( cnt + 1, pos );

if ( ans != -1 )
return;
}
}

void IDdfs () {
ans = -1;
int pos[ 10 ] = {0};

while ( ans == -1 ) {
dfs ( 0, pos );
//迭代加深搜索算法限制每一次搜索的深度最大为depth
depth++;
}
}

int main () {
int t;
scanf ( "%d", &t );
while ( t-- ) {
scanf ( "%d", &n );
depth = 0;

for ( int i = 0; i < n; ++i ) {
scanf ( "%s", str[ i ] );
depth = max ( depth, strlen ( str[ i ] ) );
}

IDdfs ();

printf ( "%d\n", ans );
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: