BZOJ1055: [HAOI2008]玩具取名

1055: [HAOI2008]玩具取名

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 820  Solved: 482
[Submit][Status]

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

 

Source

题解:

真是一道巧妙的DP!!!

OI不是考你会不会什么算法,而是看你能不能想到。真正的大牛不会因为不会码什么而不会做什么题,什么算法都随便写,只要想到。。。

这题如果有DP的想法就很简单了,dp[i][j][k]表示从 i 到 j 能否变成 k,然后就很好转移了。

OI就应该多考这种思路巧妙而代码量又不大的题目!!!

代码:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 300+100
14 #define maxm 500+100
15 #define eps 1e-10
16 #define ll long long
17 #define pa pair<int,int>
18 #define for0(i,n) for(int i=0;i<=(n);i++)
19 #define for1(i,n) for(int i=1;i<=(n);i++)
20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
21 using namespace std;
22 const char t[5]={' ','W','I','N','G'};
23 inline int read()
24 {
25     int x=0,f=1;char ch=getchar();
26     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
27     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
28     return x*f;
29 }
30 vector<int> a[5][5];
31 int num[5],n,ans;
32 bool dp[maxn][maxn][5];
33 string s;
34 inline int hash(char ch)
35 {
36     if(ch=='W')return 1;
37     if(ch=='I')return 2;
38     if(ch=='N')return 3;
39     if(ch=='G')return 4;    
40 }
41 int main()
42 {
43     freopen("input.txt","r",stdin);
44     freopen("output.txt","w",stdout);
45     for1(i,4)num[i]=read();
46     for1(i,4)
47      for1(j,num[i])
48       {
49           cin>>s;
50           a[hash(s[0])][hash(s[1])].push_back(i);
51       }
52     cin>>s;
53     n=s.length();
54     for1(i,n)dp[i][i][hash(s[i-1])]=1;  
55     for2(l,2,n)
56      for1(i,n-l+1)
57       {
58           int j=i+l-1;
59           for2(k,i,j-1)
60           for1(p,4)
61            if(dp[i][k][p])
62             for1(q,4)
63              if(dp[k+1][j][q])
64               for(int w=0;w<a[p][q].size();w++)
65                dp[i][j][a[p][q][w]]=1;
66       }
67     ans=0;
68     for1(i,4)if(dp[1][n][i])ans++,cout<<t[i];
69     if(!ans)puts("The name is wrong!");  
70     return 0;
71 }
View Code

 

posted @ 2014-09-08 10:39  ZYF-ZYF  Views(226)  Comments(0Edit  收藏  举报