「专题训练」Collecting Bugs(POJ-2096)
题意与分析
题意大致是这样的:给定一个\(n\times s\)的矩阵,每次可以随机的在这个矩阵内给一个格子染色(染过色的仍然可能被选中),问每一行和每一列都有格子被染色的次数的期望。
这题如果从概率(从正方向推)就会白给,不信你自己试试;而定义反方向的推导(\(e_{i,j}\)意为从i行j列已有染色格子到最后全被染色的次数的期望)就会非常简单:分四种情况讨论即可。
代码
#include <bits/stdc++.h>
using namespace std;
double e[1005][1005];
int n, s;
const double eps = 1e-6;
int main() {
while (cin >> n >> s) {
memset(e, 0, sizeof(e));
for (int x = n; x >= 0; --x) {
for (int y = s; y >= 0; --y) {
double p1 = x * y, p2 = (n - x) * y, p3 = x * (s - y),
p4 = (n - x) * (s - y);
if (x == n && y == s)
e[x][y] = 0;
else {
e[x][y] = (p2 * e[x + 1][y] + p3 * e[x][y + 1] +
p4 * e[x + 1][y + 1] + n * s) /
(n * s - p1);
}
}
}
cout << fixed << setprecision(4) << e[0][0] << endl;
}
return 0;
}
如非注明,原创内容遵循GFDLv1.3发布;其中的代码遵循GPLv3发布。