[IDDFS] HDU 1560

给出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;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值