Chinaunix首页 | 论坛 | 博客
  • 博客访问: 453088
  • 博文数量: 98
  • 博客积分: 6011
  • 博客等级: 准将
  • 技术积分: 1030
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-23 13:19
文章分类

全部博文(98)

文章存档

2011年(2)

2009年(2)

2008年(31)

2007年(35)

2006年(28)

我的朋友

分类:

2008-06-07 21:27:58

题目:
题目大意是说给定几个串,然后求出最短公共父串的长度。。由于串的个数,以及每个串的长度都比较小,所以直接采用搜索。先保存任意两个串合并后的长度,然后搜索出所有串合并后的最短长度。具体如下:
str[i]:保存输入的串第i个串
a[i][j]:保存第j个串加到第i个串后面时,最短需要在i串后添加的长度。如str[i]="AGCT",str[j]="CTA",则a[i][j]=1,a[j][i]=3;注意的是,如果s[j]="GC",则a[i][j]=2,即合并后的串为"AGCTGC",而不是"AGCT"。
x[i]:保存结果中第i个串,在原始串序列中的位置。
my code:
 
 

#include<iostream>
using namespace std;
char str[11][21];
int n,a[11][11],ans,use[11],x[11];
int comlen(char a[],char b[])//求b串合并到a串后,a串需要增加的长度
{
    int la,lb,j,k,t,i;
    la=strlen(a);
    lb=strlen(b);
    for(k=la>lb?la-lb:0,j=0,t=0,i=k;i<la;)
    {
        if(a[i]!=b[j]) {t=0;j=0;k++;i=k;}
        else {i++;j++;t++;}
    }
    t=lb-t;
    return t;
}
void res(int p,int len)
{
    if(p==n+1)
    {
        if(len<ans) ans=len;
        return ;
    }
    for(x[p]=1;x[p]<=n;x[p]++)
    {
        if(len+a[x[p-1]][x[p]]>ans) continue;//加个小剪枝,快了几百MS
        if(use[x[p]]) continue;
        use[x[p]]=1;
        if(p<=n) res(p+1,len+a[x[p-1]][x[p]]);
        use[x[p]]=0;
    }
}
int main()
{
    int t,i,j;
    cin>>t;
    while(t--)
    {
        cin>>n;ans=10000;
        memset(use,0,sizeof(use));
        for(i=1;i<=n;i++)cin>>str[i];
        for(i=1;i<=n;i++)
            for(j=i+1;j<=n;j++)
            {
                a[i][j]=comlen(str[i],str[j]);
                a[j][i]=comlen(str[j],str[i]);
            }
        for(i=1;i<=n;i++) a[0][i]=strlen(str[i]);
        res(1,0);
        cout<<ans<<endl;
    }
    return 0;
}

阅读(1494) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-08-23 13:52:56

2楼,输出6才能ac,输出4就错了....................

jt_feelcool2009-02-13 21:27:45

PKU的数据.....我不说了 让博主就这么侥幸AC了

chinaunix网友2008-10-13 16:35:06

1 2 AC AACC 你的程序算出是6

chinaunix网友2008-06-07 23:58:52

刚开始我也是直接暴力的,没想到TLE,10!=3628800,再加上我那个求相交部分的函数又很是慢,导致无限TLE,看来这题剪枝的效果非常好,呵呵!!!