1055: [HAOI2008]玩具取名
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1119 Solved: 653
[Submit][Status][Discuss]
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嘛,L~R用a组可不可以,每次用字典来分割区间。
又因为没有解的情况WA了一发= =。。。。。。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<stack> 6 #include<queue> 7 #include<cstring> 8 #define PAU putchar(' ') 9 #define ENT putchar(' ') 10 using namespace std; 11 const int maxn=200+10,inf=-1u>>1; 12 int id(char ch){ 13 if(ch=='W')return 0; 14 if(ch=='I')return 1; 15 if(ch=='N')return 2; 16 if(ch=='G')return 3; 17 return -1; 18 } 19 void princ(int a){ 20 if(!a)putchar('W'); 21 else if(a==1)putchar('I'); 22 else if(a==2)putchar('N'); 23 else if(a==3)putchar('G'); 24 return; 25 } 26 int t[4],tx[4][20][2],arr[maxn];int dp[4][maxn][maxn]; 27 bool solve(int a,int L,int R){ 28 int&res=dp[a][L][R];if(res!=-1)return res; 29 if(L==R)return (res=(arr[L]==a)); 30 for(int i=L;i<R;i++){ 31 for(int j=0;j<t[a];j++){ 32 if(solve(tx[a][j][0],L,i)&&solve(tx[a][j][1],i+1,R))return (res=true); 33 } 34 }return (res=false); 35 } 36 inline int read(){ 37 int x=0;bool sig=1;char ch=getchar(); 38 for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0; 39 for(;isdigit(ch);ch=getchar())x=10*x+ch-'0'; 40 return sig?x:-x; 41 } 42 inline void write(int x){ 43 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 44 int len=0,buf[20];while(x)buf[len++]=x%10,x/=10; 45 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 46 } 47 char s[maxn]; 48 int main(){ 49 for(int i=0;i<4;i++)t[i]=read(); 50 for(int i=0;i<4;i++){ 51 for(int j=0;j<t[i];j++){ 52 scanf("%s",s);tx[i][j][0]=id(s[0]);tx[i][j][1]=id(s[1]); 53 } 54 } 55 scanf("%s",s); 56 for(int i=0;s[i];i++)arr[i]=id(s[i]);int Len=strlen(s); 57 memset(dp,-1,sizeof(dp));bool flag=false; 58 for(int i=0;i<4;i++){ 59 if(solve(i,0,Len-1))princ(i),flag=true; 60 } 61 if(!flag)puts("The name is wrong!"); 62 return 0; 63 }