1055: [HAOI2008]玩具取名 - BZOJ

Description

某人有一套玩具,并想法给玩具命名。首先他选择WING四个字母中的任意一个字母作为玩具的基本名字。然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长。现在,他想请你猜猜某一个很长的名字,最初可能是由哪几个字母变形过来的。
Input

第一行四个整数W、I、N、G。表示每一个字母能由几种两个字母所替代。接下来W行,每行两个字母,表示W可以用这两个字母替代。接下来I行,每行两个字母,表示I可以用这两个字母替代。接下来N行,每行两个字母,表示N可以用这两个字母替代。接下来G行,每行两个字母,表示G可以用这两个字母替代。最后一行一个长度不超过Len的字符串。表示这个玩具的名字。
Output

一行字符串,该名字可能由哪些字母变形而得到。(按照WING的顺序输出)如果给的名字不能由任何一个字母变形而得到则输出“The name is wrong!”
Sample Input
1 1 1 1
II
WW
WW
IG
IIII

Sample Output
IN

HINT

W可以变成II所以IIII可以缩成WW IN均能变成WW所以WW又可以缩成I或者N 所以最终答案应该按照“WING”的顺序输出IN [数据范围] 30%数据满足Len<=20,W、I、N、G<=6 100%数据满足Len<=200,W、I、N、G<=16

 

直接dp,f[i,j,k]表示i到j是否能表示成k(bool型的)

 1 const

 2     maxn=205;

 3 var

 4     num:array[1..4]of longint;

 5     w:array[1..4,0..30]of string;

 6     f:array[0..maxn,0..maxn,0..4]of boolean;

 7     len:longint;

 8 

 9 function calc(ch:char):longint;

10 begin

11     case ch of

12       'W':exit(1);

13       'I':exit(2);

14       'N':exit(3);

15       'G':exit(4);

16       else exit(0);

17     end;

18 end;

19 

20 function calc(ch:longint):char;

21 begin

22     case ch of

23       1:exit('W');

24       2:exit('I');

25       3:exit('N');

26       4:exit('G');

27       else exit(' ');

28     end;

29 end;

30 

31 procedure init;

32 var

33     i,j:longint;

34     s:char;

35     str:string;

36 begin

37     for i:=1 to 4 do

38       read(num[i]);

39     readln;

40     for i:=1 to 4 do

41       for j:=1 to num[i] do

42         readln(w[i,j]);

43     readln(str);

44     len:=length(str);

45     for i:=1 to len do

46       f[i,i,calc(str[i])]:=true;

47 end;

48 

49 procedure dp;

50 var

51     i,j,k,d,l,r:longint;

52 begin

53     for i:=1 to len-1 do

54       for j:=1 to len-i do

55         for k:=1 to 4 do

56           for d:=j to j+i-1 do

57             begin

58               for l:=1 to num[k] do

59                 if (f[j,d,calc(w[k,l][1])]) and (f[d+1,j+i,calc(w[k,l][2])]) then

60                 begin

61                   f[j,j+i,k]:=true;

62                   break;

63                 end;

64               if f[j,j+i,k] then break;

65             end;

66     for i:=1 to 4 do

67       if f[1,len,i] then write(calc(i));

68     for i:=1 to 4 do

69       if f[1,len,i] then exit;

70     write('The name is wrong!');

71 end;

72 

73 begin

74     init;

75     dp;

76 end.
View Code

 

你可能感兴趣的:(2008)