题目:
有一天,蒜头君当上了国王。蒜头君的王国有 n 坐城市,现在他需要在城市之间修建道路使得城市之间相互联通。
蒜头君是一个不会规划的人,他不知道哪些城市之间必须要有道路,所以对于任意两座城市之间,蒜头军会修建道路的概率为 p。
请你计算一下最后修建出来的道路使得 n 坐城市都联通的概率。
1 <= n <= 20
分析:
用
F(n)
表示
n
个点联通的概率,
考虑第
所以 G(n)=Ck−1n−1F(k)(1−p)k(n−k) 。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ms(a,b) memset(a,b,sizeof(a))
#define lson rt*2,l,(l+r)/2
#define rson rt*2+1,(l+r)/2+1,r
typedef unsigned long long ull;
typedef long long ll;
const double EPS = 1e-8;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int MAXN = 25;
double ans[MAXN],p;
int n;
ll C(int n, int m) {
ll ret = 1;
for (int i = m + 1; i <= n; i++) {
ret *= i;
}
for (int i = 1; i <= n-m; i++) {
ret /= i;
}
return ret;
}
double Pow(double x, int m) {
double ret = 1.0;
while (m) {
if (m & 1) {
ret = ret * x;
}
x = x * x;
m >>= 1;
}
return ret;
}
int main() {
ios::sync_with_stdio(false);
cin >> n >> p;
ans[1] = 1.0;
ans[2] = p;
for (int i = 3; i <= n; i++) {
ans[i] = 1.0;
for (int k = 1; k <= i - 1; k++) {
ans[i] -= C(i - 1, k - 1) * ans[k] * Pow(1.0 - p, k * (i - k));
}
}
cout << fixed << setprecision(7) << ans[n] << endl;
return 0;
}