D - Domination ZOJ - 3822[概率dp]
阿新 • • 發佈:2018-11-07
題意:問期望多少天能把一個n*m的棋盤放成每一行每一列都至少有一個棋子的樣子,一天只能放一個。
題解:動態規劃,可以考慮
為i天放了i行和j列的概率,然後可以通過當前狀態可以轉移到下一天的概率。
如使
天 :
- 佔i行和j列
- 佔i+1行和j+1列
- 佔i行j+1列
- 佔i+1行j列
具體轉移見程式碼。
收穫:概率不是平均值,這也是為什麼暴力的結果是2.8。
/**hqx is the best**/
/*****陣列大小*****/
/**hqx is the best**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug cerr << "*" << endl;
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define pre(i, a, b) for(int i = a; i >= b; i--)
#define met(a, b) memset(a, b, sizeof(a))
const int maxn = 41 + 10;
const int inf = 0x3f3f3f3f;
int T, n, m;
double dp[maxn * maxn][maxn][maxn];
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
met(dp, 0.0);
dp[1][1][1] = 1.0;
for(int i = 1; i <= n * m; i++) {
for(int j = 1; j <= n; j++) {
for(int k = 1; k <= m; k++) {
dp[i + 1][j][k] += dp[i][j][k] * 1.0 * (j * k - i) / (double)(n * m - i);
dp[i + 1][j + 1][k] += dp[i][j][k] * 1.0 * ((n - j) * k) / (double)(n * m - i);
dp[i + 1][j][k + 1] += dp[i][j][k] * 1.0 * ((m - k) * j) / (double)(n * m - i);
dp[i + 1][j + 1][k + 1] += dp[i][j][k] * 1.0 * ((m - k) * (n - j)) / (double)(n * m - i);
}
}
}
double ans = 0.0;
for(int i = 1; i <= n * m; i++) {
ans += 1.0 * (dp[i][n][m] - dp[i - 1][n][m]) * i;
}
printf("%.10f\n", ans);
}
return 0;
}