BZOJ1055: [HAOI2008]玩具取名
1055: [HAOI2008]玩具取名
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 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
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 }