BZOJ1801 Ahoi2009 chess 中国象棋

来源:互联网 发布:慈溪楼市每日成交数据 编辑:程序博客网 时间:2024/05/17 05:51

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 longll 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;}


原创粉丝点击