首页 > 其他 > 详细

P2051中国象棋(dp)

时间:2020-10-01 10:30:29      阅读:33      评论:0      收藏:0      [点我收藏+]
inline int c(int num) {//计算 C(num,2)
	return num * (num - 1) / 2 % mod;
}

ll dp[110][110][110];//dp[row][column_1][column_2],有1个棋子的列和有两个棋子的列
int n, m;

int main() {
	scanf("%d %d", &n, &m);
	dp[0][0][0] = 1;

	for (register int i = 0; i < n; ++i) {//放第i+1行
		for (register int j = 0; j <= m; ++j) {//有1个棋子的列
			for (register int k = 0; k + j <= m; ++k) {// 有2个棋子的列
				if (dp[i][j][k]) {
					dp[i + 1][j][k] = (dp[i][j][k] + dp[i + 1][j][k]) % mod; //不放棋子
					if (m - j - k >= 1)	dp[i + 1][j + 1][k] = (dp[i + 1][j + 1][k] + dp[i][j][k] * (m - j - k)) % mod;//在没有棋子的列放一个棋子
					if (j >= 1)	dp[i + 1][j - 1][k + 1] = (dp[i + 1][j - 1][k + 1] + dp[i][j][k] * j) % mod; //在有1个棋子的列放1个棋子
					if (m - j - k >= 2)	dp[i + 1][j + 2][k] = (dp[i + 1][j + 2][k] + dp[i][j][k] * c(m - j - k)) % mod; // 在没有棋子的列放两个棋子
					if (j >= 1 && m - j - k >= 1)	dp[i + 1][j][k + 1] = (dp[i + 1][j][k + 1] + dp[i][j][k] * j * (m - j - k)) % mod; // 在没棋子的列和有1个棋子的列各放一个棋子
					if (j >= 2)	dp[i + 1][j - 2][k + 2] = (dp[i + 1][j - 2][k + 2] + dp[i][j][k] * c(j)) % mod; //在有1个棋子的列放两个棋子
				}
			}
		}
	}

	ll ans = 0;
	for (register int i = 0; i <= m; ++i) {
		for (register int j = 0; i + j <= m; ++j) {
			ans = (ans + dp[n][i][j]) % mod;
		}
	}
	printf("%lld\n", ans);
	return 0;
}

P2051中国象棋(dp)

原文:https://www.cnblogs.com/wanshe-li/p/13757309.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!