BZOJ1801 [Ahoi2009]chess 中国象棋(DP, 计数)

题目链接 [Ahoi2009]chess 中国象棋

设$f[i][j][k]$为前i行,$j$列放了1个棋子,$k$列放了2个棋子的方案数

分6种情况讨论,依次状态转移。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define rep(i, a, b) for (int i(a); i <= (b); ++i)
 6 
 7 typedef long long LL;
 8 const LL mod = 9999973;
 9 int n, m;
10 LL f[105][105][105], ans = 0;
11 
12 inline LL calc(LL x){ return x * (x - 1) / 2;}
13 
14 int main(){
15 
16         scanf("%d%d", &n, &m);
17         f[0][0][0] = 1;
18         rep(i, 1, n){ rep(j, 0, m){ rep(k, 0, m - j){
19                 f[i][j][k] = f[i - 1][j][k];
20                 if (j) f[i][j][k] += f[i - 1][j - 1][k] * (m - k - j + 1);
21                 if (j < m && k) f[i][j][k] += f[i - 1][j + 1][k - 1] * (j + 1);
22                 if (j && k) f[i][j][k] += f[i - 1][j][k -1] * j * (m - j - k + 1);
23                 if (j > 1) f[i][j][k] += f[i - 1][j - 2][k] * calc(m - k - j + 2);
24                 if (j <= m - 2 && k > 1) f[i][j][k] += f[i - 1][j + 2][k - 2] * calc(j + 2);
25                 f[i][j][k] %= mod;
26         }       }
27         }
28         
29         rep(i, 0, m) rep(j, 0, m - i) (ans += f[n][i][j]) %= mod;
30         printf("%lld\n", ans);
31         return 0;
32 }

 

posted @ 2017-04-11 21:30  cxhscst2  阅读(304)  评论(0编辑  收藏  举报