bzoj1801

题目就是每行每列最多放两个炮的意思;

首先不难想到状态压缩dp,但是当n,m<=100的时候显然会跪掉;

考虑每行最多就2个点,状压dp浪费了大量的空间

由于每行最多两个点,我们可以直接用f[i,j,k]表示状态到第i行放1个炮有j列,2个炮有k列

方程具体见程序

  1 const re=9999973;
  2 
  3 
  4 
  5 var f:array[0..1,0..110,0..110] of int64;
  6 
  7     i,j,n,p,k,m:longint;
  8 
  9     ans:int64;
 10 
 11 function c2(x:int64):int64;
 12 
 13   begin
 14 
 15     c2:=x*(x-1) div 2 mod re;
 16 
 17   end;
 18 
 19 
 20 
 21 begin
 22 
 23   readln(n,m);
 24 
 25   f[0,0,0]:=1;
 26 
 27   ans:=0;
 28 
 29   p:=0;
 30 
 31   for i:=1 to n do
 32 
 33   begin
 34 
 35     p:=1-p;
 36 
 37     for j:=0 to m do
 38 
 39       for k:=0 to m-j do
 40 
 41       begin
 42 
 43         f[p,j,k]:=f[1-p,j,k];
 44 
 45         if j>0 then
 46 
 47           f[p,j,k]:=(f[p,j,k]+f[1-p,j-1,k]*(m-j-k+1) mod re) mod re;
 48 
 49         if (k>0) and (j<m) then
 50 
 51           f[p,j,k]:=(f[p,j,k]+f[1-p,j+1,k-1]*(j+1) mod re) mod re;
 52 
 53         if (j>1) then
 54 
 55           f[p,j,k]:=(f[p,j,k]+f[1-p,j-2,k]*c2(m-j-k+2) mod re) mod re;
 56 
 57         if (j>0) and (k>0) then
 58 
 59           f[p,j,k]:=(f[p,j,k]+f[1-p,j,k-1]*(m-j-k+1)*j mod re) mod re;
 60 
 61         if (k>1) and (j<m-1) then
 62 
 63           f[p,j,k]:=(f[p,j,k]+f[1-p,j+2,k-2]*c2(j+2) mod re) mod re;
 64 
 65       end;
 66 
 67   end;
 68 
 69   for i:=0 to m do
 70 
 71     for j:=0 to m-i do
 72 
 73       ans:=(ans+f[p,i,j]) mod re;
 74 
 75   writeln(ans);
 76 
 77 end.
 78 
 79 
 80 
 81 
 82 const re=9999973;
 83 
 84 var f:array[0..1,0..110,0..110] of int64;
 85     i,j,n,p,k,m:longint;
 86     ans:int64;
 87 function c2(x:int64):int64;
 88   begin
 89     c2:=x*(x-1) div 2 mod re;
 90   end;
 91 
 92 begin
 93   readln(n,m);
 94   f[0,0,0]:=1;
 95   ans:=0;
 96   p:=0;
 97   for i:=1 to n do
 98   begin
 99     p:=1-p;
100     for j:=0 to m do
101       for k:=0 to m-j do
102       begin
103         f[p,j,k]:=f[1-p,j,k];
104         if j>0 then
105           f[p,j,k]:=(f[p,j,k]+f[1-p,j-1,k]*(m-j-k+1) mod re) mod re;
106         if (k>0) and (j<m) then
107           f[p,j,k]:=(f[p,j,k]+f[1-p,j+1,k-1]*(j+1) mod re) mod re;
108         if (j>1) then
109           f[p,j,k]:=(f[p,j,k]+f[1-p,j-2,k]*c2(m-j-k+2) mod re) mod re;
110         if (j>0) and (k>0) then
111           f[p,j,k]:=(f[p,j,k]+f[1-p,j,k-1]*(m-j-k+1)*j mod re) mod re;
112         if (k>1) and (j<m-1) then
113           f[p,j,k]:=(f[p,j,k]+f[1-p,j+2,k-2]*c2(j+2) mod re) mod re;
114       end;
115   end;
116   for i:=0 to m do
117     for j:=0 to m-i do
118       ans:=(ans+f[p,i,j]) mod re;
119   writeln(ans);
120 end.
View Code

 

转载于:https://www.cnblogs.com/phile/p/4473223.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值