【poj 1699】Best Sequence 题意&题解&代码(C++)

来源:互联网 发布:福建知鱼科技有限公司 编辑:程序博客网 时间:2024/05/01 03:41

题目链接:
http://poj.org/problem?id=1699
题意:
给出T组数据,每组数据n个字符串,要求将它按题示图片的方法组合成一个最短的字符串,求出这个最短的字符串的长度。
题解:
预处理两两相接时的最长重合长度,然后裸地暴搜,剪枝就是当前长度大于等于已经搜到的最优答时,就不搜了。
代码:

#include<iostream>#include<algorithm>#include<string.h>#include<stdio.h>using namespace std;int ans,T,n,vis[11],len[11],dou[11][11];char s[11][25];void pre()//预处理,超暴力的预处理,也可kmp,反正n小于10乱搞就行{    int flag=0;    for (int i=1;i<=n;i++)    for (int j=1;j<=n;j++)    {        for (int l=0;l<=min(len[i],len[j]);l++)        {            flag=0;            for (int x=0,y=len[j]-l;x<l;x++,y++)            if (s[i][x]!=s[j][y])             {flag=1;break;}            if (!flag)            dou[j][i]=l;        }    }}void dfs(int x,int dep,int sum){    if (sum>=ans) return ;//剪枝    if (dep==n)    {        ans=min(ans,sum);        return ;    }    for (int i=1;i<=n;i++)    if (!vis[i])    {        vis[i]=1;        dfs(i,dep+1,sum+len[i]-dou[x][i]);        vis[i]=0;    }}int main(){    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for (int i=1;i<=n;i++)        {            scanf("%s",s[i]);            len[i]=strlen(s[i]);            vis[i]=0;        }        pre();        ans=11*25;        for (int i=1;i<=n;i++)        {            vis[i]=1;            dfs(i,1,len[i]);            vis[i]=0;        }        printf("%d\n",ans);    }}
0 0