您的位置:首页 > Web前端 > JavaScript

JZOJsenior1667.【AHOI2009】中国象棋

2017-04-17 19:29 330 查看
Description

  在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮。请问有多少种放置方法?中国象棋中炮的行走方式大家应该很清楚吧.

Input

  一行包含两个整数N,M,中间用空格分开.

Output

  输出所有的方案数,由于值比较大,输出其mod 9999973

Sample Input

1 3

Sample Output

7

Data Constraint

Hint

  除了在3个格子中都放满炮的的情况外,其它的都可以.

  100%的数据中N,M不超过100

  50%的数据中,N,M至少有一个数不超过8

  30%的数据中,N,M均不超过6

  

思路:

比赛时打了个暴力,却连(6,6)也卡不过,于是打了数据库,30分

不过这题也不算很难?

正解DP算法:

f[i,j,k]表示前i行,j列放一个棋子,k列没放棋子的方案

那么分6种情况:

1、不放

2、在有一个棋子的列放一个

3、在有一个棋子的列放两个

4、在没有棋子的列放一个

5、在没有棋子的列放两个

6、在有一个棋子的列和没有棋子的列各放一个

ans=∑(0<=i<=m)(0<=j<=m-i)f[n,i,j]

按讲课时讲的思路即可

代码:

const
maxn=9999973;
var
f:array[0..100,0..100,0..100]of int64;
n,m,i,j,k,ans:longint;
function c(x:longint):longint;
begin
exit(x*(x-1)div 2 mod maxn);
end;
begin
readln(n,m);
f[0,0,0]:=1;
for i:=1 to n do
for j:=0 to m do
for k:=0 to m-j do
begin
f[i,j,k]:=f[i-1,j,k];
if k>=1 then
f[i,j,k]:=(f[i,j,k]+f[i-1,j+1,k-1]*(j+1));
if j>=1 then
f[i,j,k]:=(f[i,j,k]+f[i-1,j-1,k]*(m-j-k+1));
if j>=2 then
f[i,j,k]:=(f[i,j,k]+f[i-1,j-2,k]*c(m-j-k+2));
if k>=2 then
f[i,j,k]:=(f[i,j,k]+f[i-1,j+2,k-2]*c(j+2));
if k>=1 then
f[i,j,k]:=(f[i,j,k]+f[i-1,j,k-1]*(m-j-k+1)*j);
f[i,j,k]:=f[i,j,k]mod maxn;
end;
for i:=0 to m do
for j:=0 to m-i do
ans:=(ans+f[n,i,j])mod maxn;
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: