洛谷P2051 [AHOI2009]中国象棋

题目

运用数学知识递推。定义\(DP[i][j][k]\)为前i行内选择j个列只有一个炮,k列只有两个炮的放置方案总数。

因为如果有一列或者一行的炮大于等于三时,必会有一个炮会被攻击到,所以可以用一个和两个来区分,方便递推。这样可以使的列里面的炮不会大于等于三,然后考虑行,这一行内只能放两个或一个,所以可以考虑从这方面来推出递推公式。放的这一个或两个炮会改变列上的炮数,所以可以从上一行的炮的状态转移。

有递推公式:

dp[i][j][k] = (dp[i][j][k] + (j + 1) * dp[i - 1][j + 1][k - 1]) % mod;//j+1个列里任选一个即可有总共k个放了两个炮的列,同时j+1个放1个炮的列也变成了j个 
dp[i][j][k] = (dp[i][j][k] + j * (m - (j+k-1) ) * dp[i - 1][j][k - 1]) % mod;//j列任选一个,空列任选一个, 都放一个,即可有k个放了两个炮的列乘法原理。 
dp[i][j][k] = (dp[i][j][k] + (m - j - k + 1) * dp[i - 1][j - 1][k]) % mod//空列放一个,即可有j个放了一个炮的列。 
dp[i][j][k] = (dp[i][j][k] + C(j + 2) * dp[i - 1][j + 2][k - 2]) % mod;//j+2列里任选两个。 
dp[i][j][k] = (dp[i][j][k] + C(m - j - k + 2) * dp[i - 1][j - 2][k]) % mod;//空列里任选两个 

Code:

#include <bits/stdc++.h>
#define int long long	
const int mod =  9999973;
using namespace std;
int n, m, ans;
int dp[111][111][111];//三维数组dp[i][j][k]表示前i行内放了有j个只放了一个炮的列,k个放了两个炮的列的总方案数 
int C(int n) {return ((n * (n - 1)) / 2) %mod;} //C(n, 2),n个数里面选择2个数的组合数。 
signed main()
{
 	scanf("%lld%lld", &n, &m);
 	dp[0][0][0] = 1;
 	for (int i = 1; i <= n; i++)   
	 	for (int j = 0; j <= m; j++)
 			for (int k = 0; k <= m - j; k++)
 			{
 				dp[i][j][k] = dp[i][j][k] + dp[i - 1][j][k] % mod;
 				if (k >= 1)
 					dp[i][j][k] = (dp[i][j][k] + (j + 1) * dp[i - 1][j + 1][k - 1]) % mod;//j+1个列里任选一个即可有总共k个放了两个炮的列,同时j+1个放1个炮的列也变成了j个 
				if (k >= 1)
 					dp[i][j][k] = (dp[i][j][k] + j * (m - (j+k-1) ) * dp[i - 1][j][k - 1]) % mod;//j列任选一个,空列任选一个, 都放一个,即可有k个放了两个炮的列乘法原理。 
 				if (j >= 1)
 					dp[i][j][k] = (dp[i][j][k] + (m - j - k + 1) * dp[i - 1][j - 1][k]) % mod//空列放一个,即可有j个放了一个炮的列。 
 				if (k >= 2)
 					dp[i][j][k] = (dp[i][j][k] + C(j + 2) * dp[i - 1][j + 2][k - 2]) % mod;//j+2列里任选两个。 
 				if (j >= 2)
	 				dp[i][j][k] = (dp[i][j][k] + C(m - j - k + 2) * dp[i - 1][j - 2][k]) % mod;//空列里任选两个 
 			}
 	for (int i = 0; i <= m; i++)
 		for (int j = 0; j <= m; j++)
 			ans += dp[n][i][j], ans %= mod;//全放两个的,全放一个的和放两个和放一个都有的,都有可能出现,所以都要加上;
 			    printf("%lld", ans % mod);
 	return 0;
}	
posted @ 2019-11-03 20:53  DAGGGGGGGGGGGG  阅读(117)  评论(0编辑  收藏  举报