统计单词个数(Vijos1118)

本文分析并解决了一道看似困难的NOIP2001第三题,通过转换思路,利用动态规划(DP)算法,有效地计算出每一段区间内的单词个数,并设定了状态转移方程f[i,j]来求解包含最大单词数的最优解。重点在于理解区间长度与部分划分的关系,以及如何高效地计算区间内的单词数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法:DP
 
分析:NOIP2001年的第三题,看起来是很难做的一道题,但是经过转化就变得很容易了。
      算出每一段区间内的单词个数,然后设f[i,j]是长度为i,分成j个部分所包含的最大的单词数,则f[i,j]=max(f[k,i-1]+leng[k+1,j])。

      需要注意的是,区间的长度必须大于等于区间分成的部分。

program Vijos1118;



const

 maxlen=200;

 maxdic=6;

 maxk=40;



var

 f:array [0..maxlen,0..maxk] of longint;

 leng:array [0..maxlen,0..maxlen] of longint;

 dict:array [0..maxdic] of string;

 b:array [0..maxlen] of boolean;

 n,m,len,tot:longint;

 s:string;



procedure init;

var

 i:longint;

 x:ansistring;

begin

 s:='';

 readln(n,m);

 for i:=1 to n do

  begin

   readln(x);

   s:=s+x;

  end;

 len:=length(s);

 readln(tot);

 for i:=1 to tot do readln(dict[i]);

end;



function calc(st,ed:longint):longint;{计算区间内的单词个数,这个是这道题的主要部分。}

var

 i,t:longint;

 temp,temp_:string;

begin

 calc:=0;

 for i:=1 to ed-st+1 do b[i]:=true;

 temp:=copy(s,st,ed-st+1);

 for i:=1 to tot do

  begin

   temp_:=temp;

   repeat

    t:=pos(dict[i],temp_);{找单词位置。}

    temp_[t]:='

;{保证了单词的头不被重复使用的问题。} if (t>0) and (b[t]) then begin inc(calc); b[t]:=false; end; until t=0; end; exit(calc);end;procedure before;var i,j:longint;begin for i:=1 to len do begin for j:=1 to len do leng[i,j]:=calc(i,j); end;end;function max(x,y:longint):longint;begin if x>y then exit(x) else exit(y);end;procedure main;var i,j,k,t:longint;begin for i:=1 to m do{应该放在最外层,因为是分成几部分。} begin for j:=1 to len do begin for k:=j-1 downto i-1 do begin t:=leng[k+1,j]; f[j,i]:=max(f[j,i],f[k,i-1]+t); end; end; end;end;begin assign(input,'VJ1118.in'); reset(input); assign(output,'VJ1118.out'); rewrite(output); init; before; main; writeln(f[len,m]); close(input); close(output);end.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值