USACO-Section 2.3 Longest Prefix (DP)

58 篇文章 0 订阅

描述

在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的。生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣。

如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素。元素不一定要全部出现(如下例中BBC就没有出现)。举个例子,序列 ABABACABAAB 可以分解为下面集合中的元素:

{A, AB, BA, CA, BBC}

序列 S 的前面 K 个字符称作 S 中长度为 K 的前缀。设计一个程序,输入一个元素集合以及一个大写字母序列 S ,设S'是序列S的最长前缀,使其可以分解为给出的集合P中的元素,求S'的长度K。

格式

PROGRAM NAME: prefix

INPUT FORMAT:

(file prefix.in)

输入数据的开头包括 1..200 个元素(长度为 1..10 )组成的集合,用连续的以空格分开的字符串表示。字母全部是大写,数据可能不止一行。元素集合结束的标志是一个只包含一个 “.” 的行。集合中的元素没有重复。接着是大写字母序列 S ,长度为 1..200,000 ,用一行或者多行的字符串来表示,每行不超过 76 个字符。换行符并不是序列 S 的一部分。

OUTPUT FORMAT:

(file prefix.out)

只有一行,输出一个整数,表示 S 符合条件的前缀的最大长度。

SAMPLE INPUT

A AB BA CA BBC
.
ABABACABAABC

SAMPLE OUTPUT

11

第一反应是dfs,但复杂度太高,估计会超时

又想到可以对于每一个合法位置,可以通过集合内的字符串往后扩展,如果扩展成功则将更新答案最大值


/*
ID: your_id_here
PROG: prefix
LANG: C++
*/
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int cnt=0,ans=0,i=0,len,j,k;
char s[200015]={0},tmp[77];
bool dp[200015]={false};

struct Node {
    char s[11];
    int len;
}pri[205];

bool mycmp() {
    for(k=0;k<pri[j].len;++k)
        if(s[i+k+1]!=pri[j].s[k])
            return false;
    return true;
}

int main() {
    freopen("prefix.in","r",stdin);
    freopen("prefix.out","w",stdout);
    while(scanf("%s",pri[cnt].s),pri[cnt].s[0]!='.') {
        pri[cnt].len=strlen(pri[cnt].s);
        ++cnt;
    }
    while(1==scanf("%s",tmp)) {//s串可以分成多行
        strcpy(s+1+len,tmp);
        len+=strlen(tmp);
    }
    dp[0]=true;
    while(i<=ans&&i<=len) {
        if(dp[i])
            for(j=0;j<cnt;++j)
                if(!dp[i+pri[j].len]&&mycmp()) {
                    dp[i+pri[j].len]=true;
                    ans=max(ans,i+pri[j].len);
                }
        ++i;
    }
    printf("%d\n",min(len,ans));
    return 0;
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值