BZOJ 1055 玩具取名

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 

[数据范围]

100%数据满足Len<=200,W、I、N、G<=16


 

 

Source

 

 么么的,区间dp我又没有看出来,我是不是老了。。。。QAQ
f[i][j][k]表示i到j这段区间是否可以合成字母k,然后就没有然后了,脑补吧!!!
 
 1 #include<cstring>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 using namespace std;
 5 
 6 #define maxn 210
 7 bool f[maxn][maxn][5];int n[5],vec[5][16];
 8 
 9 inline int change(char ch)
10 {
11     switch (ch)
12     {
13         case 'W': return 1; break;
14         case 'I': return 2; break;
15         case 'N': return 3; break;
16         default: return 4; break;
17     }
18 }
19 
20 inline void dp()
21 {
22     char s[maxn]; scanf("%s",s+1); int l = strlen(s+1);
23     for (int i = 1;i <= l;++i) f[i][i][change(s[i])] = true;
24     for (int i = 2;i <= l;++i)
25         for (int j = 1;j+i-1 <= l;++j)
26             for (int k = 1;k <= 4;++k)
27                 for (int p = 1;p <= n[k]&&!f[j][j+i-1][k];++p)
28                     for (int q = j;q < j+i-1;++q)
29                         if (f[j][q][vec[k][p]/10]&f[q+1][j+i-1][vec[k][p]%10])
30                             { f[j][j+i-1][k] = true; break; }
31     bool sign = false;
32     for (int i = 1;i <= 4;++i)
33         if (f[1][l][i])
34         {
35             sign = true;
36             switch (i)
37             {
38                 case 1: putchar('W'); break;
39                 case 2: putchar('I'); break;
40                 case 3: putchar('N'); break;
41                 default: putchar('G'); break; 
42             }
43         }
44     if (!sign) printf("The name is wrong!");
45 }
46 
47 int main()
48 {
49     freopen("1055.in","r",stdin);
50     freopen("1055.out","w",stdout);
51     for (int i = 1;i <= 4;++i) scanf("%d\n",n+i);
52     for (int i = 1;i <= 4;++i)
53         for (int j = 1;j <= n[i];++j)
54         {
55             char opt[4]; scanf("%s",opt);
56             int t = 10*change(opt[0])+change(opt[1]);
57             vec[i][j] = t;
58         }
59     dp();
60     fclose(stdin); fclose(stdout);
61     return 0;
62 }
View Code

 

posted @ 2015-02-22 20:00  lmxyy  阅读(353)  评论(0编辑  收藏  举报