BZOJ1801 Ahoi2009 chess 中国象棋

8 篇文章 0 订阅

1801: [Ahoi2009]chess 中国象棋

Time Limit: 10 Sec   Memory Limit: 64 MB
Submit: 1911   Solved: 1105
[ Submit][ Status][ Discuss]

Description

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

Input

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

Output

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

Sample Input

1 3

Sample Output

7

HINT

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

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

【题解】题目大意,n*m的棋盘中放棋子,每行每列不得超过2个

      dp即可,好像可以滚一下?没必要。。懒。。
#include <bits/stdc++.h>
using namespace std;
#define maxn 105
#define p 9999973
#define ll long long
ll dp[105][105][105];
ll C(int n)
{
	return (n*(n-1)/2);
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	dp[0][0][0]=1;
	for (int i=0;i<n;i++)
		for (int j=0;j<=m;j++)
			for (int k=0;j+k<=m;k++)
			{
				 dp[i+1][j][k]=(dp[i+1][j][k]+dp[i][j][k])%p;
				 if (m-j-k>0)dp[i+1][j+1][k]=(dp[i+1][j+1][k]+dp[i][j][k]*(m-j-k))%p;
				 if (m-k-j>1)dp[i+1][j+2][k]=(dp[i+1][j+2][k]+dp[i][j][k]*C(m-j-k))%p;
				 if (j>0)dp[i+1][j-1][k+1]=(dp[i+1][j-1][k+1]+dp[i][j][k]*j)%p;
				 if (j>0 && m-j-k>0)dp[i+1][j][k+1]=(dp[i+1][j][k+1]+dp[i][j][k]*j*(m-j-k))%p;
				 if (j>1)dp[i+1][j-2][k+2]=(dp[i+1][j-2][k+2]+dp[i][j][k]*C(j))%p;
			}
	ll ans=0;
	for (int i=0;i<=m;i++)
		 for (int j=0;(i+j)<=m;j++)
			 (ans+=dp[n][i][j])%=p;
	cout<<ans<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值