Longest Prefix_usaco 2.3.1_dp

99 篇文章 0 订阅
52 篇文章 0 订阅

题目描述 Description


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

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

{A, AB, BA, CA, BBC}

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

输入描述 Input Description


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

输出描述 Output Description


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

题解 Analysis


说实话看到字符串就怂了:-(
最近真是熟能生巧, dp 做♂多了也会熟练(为什么我会这么熟练啊~)

考虑 f[i] 表示到第 i 位的前缀匹配情况,则有f[i]=f[j] (w[1..j]==s[ij+1..i] f[j]==true)
其中 w 是给出的元素,s是题目中的 s 序列
初始状态f[0]=true,实测往后推可能好做些

源代码 Source Code


{
ID:wjp13241
PROG:prefix
LANG:PASCAL
}
var
  s:ansistring;
  words:array[0..201]of string;
  f:array[0..200001]of boolean;
  count:longint;
procedure main;
var
  i,j:longint;
begin
  f[0]:=true;
  for i:=0 to length(s) do
  if (f[i]) then
    for j:=1 to count do
      if (length(words[j])+i<=length(s)) then
        if (copy(s,i+1,length(words[j]))=words[j]) then
          f[i+length(words[j])]:=true;
  for i:=length(s) downto 0 do
    if (f[i]) then
    begin
      writeln(i);
      exit;
    end;
end;
procedure init;
var
  ch:string;
  i:longint;
begin
  readln(ch);
  while ch<>'.' do
  begin
    inc(count);
    for i:=1 to length(ch) do
      if (ch[i]=' ') then
        inc(count)
      else
        words[count]:=words[count]+ch[i];
    readln(ch);
  end;
  while not eof do
  begin
    readln(ch);
    s:=s+ch;
  end;
end;
begin
  assign(input,'prefix.in');
  assign(output,'prefix.out');
  reset(input);
  rewrite(output);
  init;
  main;
  close(input);
  close(output);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值