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
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 }
高考结束,重新回归。