传送门
动归。
设f[i][j][k][0/1]表示处理完前i张,i-1位置上剩j张,i剩k张,有无对子出现是否可行。
转移枚举出2对子,3对子,4对子还是顺子。
const len=100;
var
f,g:array [-5..105,-5..105,-5..105] of boolean;
a:array [-5..105] of longint;
n,t,i,j,k:longint;
begin
read(n);
for t:=1 to n do begin
for i:=1 to len do read(a[i]);
fillchar(f,sizeof(f),false);
fillchar(g,sizeof(g),false);
f[0,0,0]:=true;
for i:=1 to len do
for j:=0 to a[i-1] do
for k:=0 to a[i] do
begin
if (k>1) then g[i,j,k]:=g[i,j,k] or f[i,j,k-2];
if (k>2) then g[i,j,k]:=g[i,j,k] or g[i,j,k-3];
if (k>3) then g[i,j,k]:=g[i,j,k] or g[i,j,k-4];
if (j>=k) and (a[i-2]>=k) then
g[i,j,k]:=g[i,j,k] or g[i-1,a[i-2]-k,j-k];
if (k>2) then f[i,j,k]:=f[i,j,k] or f[i,j,k-3];
if (k>3) then f[i,j,k]:=f[i,j,k] or f[i,j,k-4];
if (j>=k) and (a[i-2]>=k) then
f[i,j,k]:=f[i,j,k] or f[i-1,a[i-2]-k,j-k];
end;
if g[len,a[len-1],a[len]] then writeln('Yes') else writeln('No');
end;
end.