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
Source
用f[i][j][k]在前i行有j行放了一个炮,有k行放了两个炮。
所以这道题的转移有6种
1.不放
2.在未放过的一列放一个
3.在已经放一个的一列放一个
4.在未放过的一列放两个
5.在已经放过一个的两列各放一个
6.分别在未放过的和已经放一个的一列各放一个
#include<cstdio> typedef long long ll; const int mod=9999973; int f[105][105][105]; int main() { int n,m,ans=0; scanf("%d%d",&n,&m); f[0][0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) for(int k=0;k+j<=m;k++) { f[i][j][k]=f[i-1][j][k]; if(j) f[i][j][k]+=(ll)(m-j-k+1)*f[i-1][j-1][k]%mod,f[i][j][k]%=mod; if(k) f[i][j][k]+=((ll)(j+1)*f[i-1][j+1][k-1]+(ll)(m-j-k+1)*j%mod*f[i-1][j][k-1])%mod,f[i][j][k]%=mod; if(k>1) f[i][j][k]+=((ll)(j+2)*(j+1)/2%mod*f[i-1][j+2][k-2])%mod,f[i][j][k]%=mod; if(j>1) f[i][j][k]+=(ll)(m-j+2-k)*(m-j+1-k)/2%mod*f[i-1][j-2][k]%mod,f[i][j][k]%=mod; if(i==n) ans+=f[i][j][k],ans%=mod; } printf("%d",ans); return 0; }