P3830随机树(概率dp,好难啊!)
题目描述:
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 10000005; const int inf = 0x3f3f3f3f; const int mod = 19260817; int q, n; double f[maxn], dp[105][105]; int main() { //freopen("test.txt", "r", stdin); scanf("%d%d", &q, &n); if (q == 1) { f[1] = 0; for (int i = 2; i <= n; i++) { f[i] = f[i - 1] + 2.0 / i; } printf("%.6lf\n", f[n]); } else { //dp[i][j]表示i个叶子,高度大于等于j的概率 for (int i = 1; i <= n; i++) {//高度大于等于0是必然的 dp[i][0] = 1; } for (int i = 2; i <= n; i++) {// for (int j = 1; j < i; j++) { for (int k = 1; k < i; k++) {//对i-1种可能的情况下的概率求和 //左子树和右子树在不同高度下的概率 dp[i][j] += dp[k][j - 1] + dp[i - k][j - 1] - dp[k][j - 1] * dp[i - k][j - 1]; } dp[i][j] /= double(i-1);//除去i-1得到期望概率 } } double ans = 0; for (int i = 1; i < n; i++) {//对叶子数为n的不同高度下的概率求和即是期望高度(别问为什么,问就是不知道). ans += dp[n][i]; } printf("%.6lf\n", ans); } return 0; }