现在的位置: 首页 > 综合 > 正文

POJ 1699 Best Sequence

2018年04月25日 ⁄ 综合 ⁄ 共 1478字 ⁄ 字号 评论关闭

这道题,居然用错误的方法也可以AC,好吧,我看了比人写的代码,自己弄个数据进去了,好多wa了.

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

题意是给你很多子序列,让你求最短父序列.

先说这道题的思路:

先预处理出来每两个子序列a,b,a添加到b后面最少添加多少个字符,并保存到add[a][b].

用dfs处理一下,枚举顺序,既然我们已经枚举顺序了,所以我们dfs的时候只需考虑b加到a后面就可以了,那a加到b后面的情况呢?因为是dfs所以肯定会遍历到,所以

我们只要默认添加在后面就好啦

为什么这样的算法可以呢?我一开始是感觉不可以的

以为这个是两两判断的所以

例如这个数据

3

ABC

A

B

这样就会出错,答案变成4,其实应该是5

其实我们只要这样做就可以了

dfs的时候记录这个决策前面的那个字符串的编号,为pre,如果add[pre][i] ==0  那就是说i串可以被pre串完全容纳,位置有可能是在前面,比如pre串为ABCD ,i串为ABC,

那么后面的状态还是得依靠前面的pre串,来,所以pre不改变,那么不等于0呢,ABC CD ,那当然是ABCD所以后面的要和CD比较,要特别注意这点,

虽然不注意也可以AC,估计是题的#include <iostream>

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
using namespace std;
const int MAXN=11;
bool vis[MAXN];
int n;
int len;
string str[MAXN];
int add[MAXN][MAXN];
int pos[MAXN],order[MAXN];
int cal(string &a,string &b)
{
    int alen=a.size(),blen=b.size();
    for(int i=0; i<a.size(); i++)
    {
        bool ok=true;
        for(int j=0;j<blen && i+j<alen;j++)
        {
            if(a[j+i]!=b[j])
            {
                ok=false;
                break;
            }
        }
        if(ok)
            return max(i+blen-alen,0);
    }
    return blen;
}
void dfs(int pre,int cnt,int sum)
{
    if(sum>=len) return ;
    if(cnt==n)
    {
        len=min(len,sum);
        return ;
    }
    for(int i=0; i<n; i++)
    {
        if(!vis[i])
        {
            vis[i]=true;
            if(pre!=-1)
                if(add[pre][i]!=0)
                    dfs(i,cnt+1,sum+add[pre][i]);
                else
                    dfs(pre,cnt+1,sum);
            else
                dfs(i,cnt+1,sum+str[i].size());
            vis[i]=false;
        }
    }
}
int main()
{
//    freopen("in","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        len=1<<30;
        memset(vis,0,sizeof(vis));
        scanf("%d",&n);
        for(int i=0; i<n; i++) cin>>str[i];
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                if(i!=j)
                    add[i][j]=cal(str[i],str[j]);
        dfs(-1,0,0);
        cout<<len<<endl;
    }
    return 0;
}

抱歉!评论已关闭.