传送门
DP.
另f[i][j][k]表示i到j这一段字符能否由k合成
转移:f[i][l][a]&&f[l+1][j][b]&&k->ab(i<=l
var
p:array [1..4] of longint;
a,b:array [1..4,0..20] of longint;
f:array [0..205,0..205,1..4] of longint;
i,j,k,l,m,fl,len:longint;
ch:char;
str:string;
begin
for i:=1 to 4 do read(p[i]);
readln;
for i:=1 to 4 do
for j:=1 to p[i] do
begin
read(ch);
case ch of
'W':a[i,j]:=1;
'I':a[i,j]:=2;
'N':a[i,j]:=3;
'G':a[i,j]:=4;
end;
readln(ch);
case ch of
'W':b[i,j]:=1;
'I':b[i,j]:=2;
'N':b[i,j]:=3;
'G':b[i,j]:=4;
end;
end;
readln(str);
fillchar(f,sizeof(f),0);
len:=length(str);
for i:=1 to len do
case str[i] of
'W':f[i,i,1]:=1;
'I':f[i,i,2]:=1;
'N':f[i,i,3]:=1;
'G':f[i,i,4]:=1;
end;
for i:=2 to len do
for j:=1 to len-i+1 do
for k:=j to j+i-2 do
for l:=1 to 4 do
for m:=1 to p[l] do
f[j,j+i-1,l]:=f[j,j+i-1,l] or (f[j,k,a[l,m]] and f[k+1,j+i-1,b[l,m]]);
fl:=0;
if (f[1,len,1]=1) then begin write('W'); fl:=1; end;
if (f[1,len,2]=1) then begin write('I'); fl:=1; end;
if (f[1,len,3]=1) then begin write('N'); fl:=1; end;
if (f[1,len,4]=1) then begin write('G'); fl:=1; end;
if fl=0 then write('The name is wrong!');
end.