bzoj1079: [SCOI2008]着色方案

传送门
普通记忆化搜索绝逼爆掉。
但是我们发现能涂i个的油漆实质上是相同的。
得到状态f[a][b][c][d][e][i],表示涂1个的有a个,2个的有b个,3个的有c个,4个的有d个,5个的有e个,上一个涂的是l的方案数。
然后一波记忆化水过。

var
  ma:array [0..15,0..15,0..15,0..15,0..15,0..5] of boolean;
  f:array [0..15,0..15,0..15,0..15,0..15,0..5] of int64;
  x:array [1..5] of int64;
  n,i,t:longint;
function dp(a,b,c,d,e,k:int64):int64;
  var tem:int64;
  begin
    if ma[a,b,c,d,e,k] then exit(f[a,b,c,d,e,k]);
    if (a+b+c+d+e=0) then begin
      ma[a,b,c,d,e,k]:=true;
      f[a,b,c,d,e,k]:=1;
      exit(1);
    end;
    tem:=0;
    if (a<>0) then
      if (k<>2) then tem:=tem+a*dp(a-1,b,c,d,e,1)
        else tem:=tem+(a-1)*dp(a-1,b,c,d,e,1);
    if (b<>0) then
      if (k<>3) then tem:=tem+b*dp(a+1,b-1,c,d,e,2)
        else tem:=tem+(b-1)*dp(a+1,b-1,c,d,e,2);
    if (c<>0) then
      if (k<>4) then tem:=tem+c*dp(a,b+1,c-1,d,e,3)
        else tem:=tem+(c-1)*dp(a,b+1,c-1,d,e,3);
    if (d<>0) then
      if (k<>5) then tem:=tem+d*dp(a,b,c+1,d-1,e,4)
        else tem:=tem+(d-1)*dp(a,b,c+1,d-1,e,4);
    if (e<>0) then tem:=tem+e*dp(a,b,c,d+1,e-1,5);
    ma[a,b,c,d,e,k]:=true;
    f[a,b,c,d,e,k]:=tem mod 1000000007;
    exit(f[a,b,c,d,e,k]);
  end;
begin
  read(n);
  for i:=1 to n do begin read(t); inc(x[t]); end;
  write(dp(x[1],x[2],x[3],x[4],x[5],0));
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值