bzoj1860: [Zjoi2006]Mahjong麻将

传送门
动归。
设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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值