BZOJ 1055 区间DP
1055: [HAOI2008]玩具取名
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1144 Solved: 668
[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
题解:暴力区间DP
#include<cstdio> #include<iostream> #include<cstring> #include<vector> using namespace std; #define maxn 201 vector<int > mp[maxn]; int a,b,c,d,sum; char ch[3],s[201]; int dp[201][201][101]; char next[400]; int str[555]; void stt(char a[]) { sum=0; if(a[0]=='W') { sum+=1; }else if(a[0]=='I')sum+=2;else if(a[0]=='N')sum+=3;else if(a[0]='G')sum+=4; sum*=10; if(a[1]=='W') { sum+=1; }else if(a[1]=='I')sum+=2;else if(a[1]=='N')sum+=3;else if(a[1]='G')sum+=4; } int main() { next[1]='W';str['W']=1; next[2]='I';str['I']=2; next[3]='N';str['N']=3; next[4]='G';str['G']=4; scanf("%d%d%d%d",&a,&b,&c,&d); for(int i=1;i<=a;i++) { scanf("%s",ch); stt(ch); //cout<<sum<<endl; mp[sum].push_back(1); } for(int i=1;i<=b;i++) { scanf("%s",ch); stt(ch); mp[sum].push_back(2); } for(int i=1;i<=c;i++) { scanf("%s",ch); stt(ch); mp[sum].push_back(3); } for(int i=1;i<=d;i++) { scanf("%s",ch); stt(ch); mp[sum].push_back(4); } scanf("%s",s); memset(dp,0,sizeof(dp)); for(int i=0;i<strlen(s);i++){ dp[i][i][str[s[i]]]=1; } int n=strlen(s); for(int l=2;l<=n;l++) { for(int i=0;i<n-l+1;i++) { for(int k=i;k<i+l-1;k++) { for(int j=1;j<=4;j++) for(int h=1;h<=4;h++) { if(dp[i][k][j]&&dp[k+1][i+l-1][h]) { for(int f=0;f<mp[j*10+h].size();f++) { dp[i][i+l-1][mp[j*10+h][f]]=1; } } } } } } int flag=0; for(int i=1;i<=4;i++) if(dp[0][n-1][i])cout<<next[i],flag=1; if(!flag)cout<<"The name is wrong!"; cout<<endl; return 0; }