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

本文介绍了解决Ahoi2009中的一道中国象棋问题的方法,通过定义状态$f[i][j][k]$来表示前$i$行,第$j$列放置1个棋子,第$k$列放置2个棋子的所有可能方案数量,并详细解释了六种状态转移的情况。

题目链接 [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 }

 

转载于:https://www.cnblogs.com/cxhscst2/p/6696474.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值