这题我已开始sb了
相邻的两个字母合并我想到只有2^i才可能有解了
回归正题
让f[i][j][k]表示i到j能否合并出k来k=0,1,2,3分别对应W,I,N,G
然后暴力转移就好了
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
#include<iostream>
using namespace std;
char s[222],z[4];
int a[16][4],f[222][222][4],y[333],q[4];
int n,flag;
void cal(char *s,int x){a[y[s[0]]*4+y[s[1]]][x]=1;}
int main()
{
for(int i=0;i<4;i++)cin>>q[i];
y['W']=0,y['I']=1,y['N']=2,y['G']=3;
z[0]='W',z[1]='I',z[2]='N',z[3]='G';
for(int i=0;i<4;i++)
for(int j=1;j<=q[i];j++)
{
char w[22];
scanf("%s",w);
cal(w,i);
}
scanf("%s",s+1);
n=strlen(s+1);
for(int i=1;i<=n;i++)f[i][i][y[s[i]]]=1;
for(int i=n;i>=1;i--)
for(int j=i+1;j<=n;j++)
for(int k=i;k<j;k++)
for(int c1=0;c1<4;c1++)
if(f[i][k][c1])
for(int c2=0;c2<4;c2++)
if(f[k+1][j][c2])
{
int x=c1*4+c2;
for(int c=0;c<4;c++)
if(a[x][c])
f[i][j][c]=1;
}
for(int i=0;i<4;i++)
if(f[1][n][i]) flag=1,cout<<z[i];
if(!flag)puts("The name is wrong!");
return 0;
}