区间dp。记录可行性即可。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int c[5],len; bool f[205][205][5],mp[50][5],flag; char ch1,ch2; char gt() { char tmp; scanf("%c",&tmp); while(tmp<65||tmp>90)scanf("%c",&tmp); return tmp; } int num(char c) { if(c=='W')return 1;if(c=='I')return 2; if(c=='N')return 3;if(c=='G')return 4; } char chr(int a) { if(a==1)return 'W';if(a==2)return 'I'; if(a==3)return 'N';if(a==4)return 'G'; } int main() { scanf("%d%d%d%d",&c[1],&c[2],&c[3],&c[4]); for(int i=1;i<=4;i++) for(int j=1;j<=c[i];j++) { scanf(" %c%c",&ch1,&ch2); mp[num(ch1)*10+num(ch2)][i]=1; } ch1=gt(); while(++len) { f[len][len][num(ch1)]=1; scanf("%c",&ch1); if(ch1==' ')break; } for(int i=2;i<=len;i++) { int lm=len-i+1; for(int l=1;l<=lm;l++) { int r=l+i-1; for(int k=l;k<r;k++) for(int x=1;x<=4;x++) if(f[l][k][x]) for(int y=1;y<=4;y++) if(f[k+1][r][y]) for(int j=1;j<=4;j++) f[l][r][j]|=mp[x*10+y][j]; } } for(int i=1;i<=4;i++) if(f[1][len][i])printf("%c",chr(i)),flag=1; if(!flag)printf("The name is wrong!"); return 0; }