首页 > 代码库 > ZOJ 3822 Domination

ZOJ 3822 Domination

题意:

一个棋盘如果每行每列都有棋子那么这个棋盘达到目标状态  现在随机放棋子  问达到目标状态的期望步数

思路:

用概率来做  计算第k步达到目标状态的概率  进而求期望  概率计算方法就是dp  dp[k][i][j]表示第k步有i行被覆盖j列被覆盖  转移只有4种  —— 同时覆盖行列  覆盖行  覆盖列  不覆盖  状态数50^4  很简单

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef long long LL;
#define N 55

int t, n, m;
double dp[N * N][N][N], ans;

int main() {
	int i, j, k;
	scanf("%d", &t);
	while (t--) {
		memset(dp, 0, sizeof(dp));
		dp[0][0][0] = 1;
		ans = 0;
		scanf("%d%d", &n, &m);
		for (k = 1; k <= n * m; k++) {
			for (i = 0; i <= n; i++) {
				for (j = 0; j <= m; j++) {
					if (i == n && j == m)
						break;
					int f00 = i * j - k + 1;
					int f01 = i * (m - j);
					int f10 = (n - i) * j;
					int f11 = (n - i) * (m - j);
					int sum = n * m - k + 1;
					dp[k][i][j] += dp[k - 1][i][j] * f00 / sum;
					dp[k][i + 1][j] += dp[k - 1][i][j] * f10 / sum;
					dp[k][i][j + 1] += dp[k - 1][i][j] * f01 / sum;
					dp[k][i + 1][j + 1] += dp[k - 1][i][j] * f11 / sum;
				}
			}
			ans += dp[k][n][m] * k;
		}
		printf("%.10f\n", ans);
	}
	return 0;
}


ZOJ 3822 Domination