pku 1699 Best Sequence DFS+剪枝

http://poj.org/problem?id=1699

题意:

现在给出几个基因片段,要求你将它们排列成一个最短的序列,序列中使用了所有的基因片段,而且不能翻转基因。,这些基因可以重叠,只要一个基因的后段和一个基因的前端一样,就可以将其重叠链接在一起。现问将这些 基因全部排列出来,最短的长度为多少。

思路:

给出的数据量比较小相信爆搜+剪枝是可以的。首先是要预处理一下每两个基因片段合并时能够增加的长度,便于以后dfs时,直接求和就可以。

View Code
#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<map>

#include<stack>

#include<cmath>

#define LL long long

#define maxn 25

#define N 13

using namespace std;



const int inf = 0x7fffffff;

char str[N][maxn];

int addlen[N][N];

int len[N];

int ans,n;

bool vt[N];



int getlen(int x,int y)

{

    int i,j,l;

    int L = 0;

    //预处理x,y基因片段合并时增加的长度

    for (l = 0; l <= len[x] && l <= len[y]; ++l)

    {

        bool flag = false;

        for (i = len[x] - l, j = 0; i < len[x] && j < l; ++i,++j)

        {

            if (str[x][i] != str[y][j])

            {

                flag = true; break;

            }

        }

        if (!flag) L = l;

    }

    return len[y] - L;

}



void init()

{

    int i,j;

    ans = inf;

    memset(vt,false,sizeof(vt));

    memset(addlen,0,sizeof(addlen));

    for (i = 0; i < n; ++i)

    {

        for (j = 0; j < n; ++j)

        {

            addlen[i][j] = getlen(i,j);

        }

    }

}

void dfs(int u,int num,int sum)

{

    if (sum >= ans) return ;//可行性剪枝

    if (num == n)

    {

        if (sum < ans) ans = sum;

        return ;

    }

    for (int i = 0; i < n; ++i)

    {

        if (!vt[i])

        {

            vt[i] = true;

            dfs(i,num + 1,sum + addlen[u][i]);

            vt[i] = false;

        }

    }

}

int main()

{

    //freopen("d.txt","r",stdin);

    int t,i;

    scanf("%d",&t);

    while (t--)

    {

        scanf("%d",&n);

        for (i = 0; i < n; ++i)

        {

            scanf("%s",str[i]);

            len[i] = strlen(str[i]);

        }

        init();

        for (i = 0; i < n; ++i)

        {

            vt[i] = true;

            dfs(i,1,len[i]);

            vt[i] = false;

        }

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

    }

    return 0;

}

 

 

 

你可能感兴趣的:(sequence)