(昨天的)codevs 天梯 統計單詞個數 dp

題目:

給出一個長度不超過200的由小寫英文字母組成的字母串(約定;該字串以每行20個字母的方式輸入,且保證每行一定爲20個)。要求將此字母串分成k份(1<k<=40),且每份中包含的單詞個數加起來總數最大(每份中包含的單詞可以部分重疊。當選用一個單詞之後,其第一個字母不能再用。例如字符串this中可包含this和is,選用this之後就不能包含th)(管理員注:這裏的不能再用指的是位置,不是字母本身。比如thisis可以算做包含2個is)。
單詞在給出的一個不超過6個單詞的字典中。
要求輸出最大的個數。

分析:

f[i,j]表示前i個字母分成j份所含的單詞數,dis[l+1,i]表示從l+1到i位所含的單詞數,則狀態轉移方程爲:f[i,j]=max(f[l,j-1]+total[l+1,i]) 

代碼:

const
  maxn=200;


var
  f:array [0..maxn,0..maxn] of longint;
  dis:array [0..maxn,0..maxn] of longint;
  flag:array [0..maxn] of boolean;
  s1:array [1..10] of string;
  n,m,num,temp:longint;
  st,s2:string;


function max(a,b:longint):longint;
begin
  if a>b then
    exit(a)
  else
    exit(b);
end;


function work(num1,num2:longint):longint;
var
  i:longint;
begin
  work:=0;
  for i:=1 to num do
    if (num2-length(s1[i])+1>=num1) and flag[num2-length(s1[i])+1] and(copy(st,num2-length(s1[i])+1,length(s1[i]))=s1[i]) then
      begin
        inc(work);
        flag[num2-length(s1[i])+1]:=false;
      end;
end;


function try(num:longint):longint;
var
  i:longint;
begin
  try:=0;
  for i:=1 to num do
    if (st[num]=s1[i]) and flag[num] then
      begin
        flag[num]:=false;
        exit(1);
      end;
end;


procedure init;
var
  i,j,k,l,z:longint;
begin
  readln(m);
  for z:=1 to m do
    begin
      fillchar(f,sizeof(f),0);
      readln(temp,k);
      st:='';
      for i:=1 to temp do
        begin
          readln(s2);
          st:=st+s2;
        end;
      n:=temp*20;
      readln(num);
      for i:=1 to num do
        readln(s1[i]);
      for i:=1 to n do
        begin
          fillchar(flag,sizeof(flag),true);
          for j:=i to n do
            if i<>j then
              dis[i,j]:=dis[i,j-1]+work(i,j)
            else
              dis[i,j]:=try(j);
        end;
      for i:=1 to n do
        f[i,1]:=dis[1,i];
      for i:=2 to n do
        for j:=2 to k do
          if j<i then
            for l:=j to i-1 do
              f[i,j]:=max(f[l,j-1]+dis[l+1,i],f[i,j]);
      writeln(f[n,k]);
    end;
end;


begin
  init;
end.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章