In 0th day, there are n-1 people and 1 bloodsucker.Every day, two and only two of them meet. Nothing will happen if they are of the same species, that is, a people meets a people or a bloodsucker meets a bloodsucker. Otherwise, people may be transformed into bloodsucker with probability p.Sooner or later(D days), all people will be turned into bloodsucker.Calculate the mathematical expectation of D.
The number of test cases (T, T ≤ 100) is given in the first line of the input.Each case consists of an integer n and a float number p (1 ≤ n < 100000, 0 < p ≤ 1, accurate to 3 digits after decimal point), separated by spaces.
For each case, you should output the expectation(3 digits after the decimal point) in a single line.
这题应该有2个思路,我是按吸血鬼数目来dp的,设dp[i] 表示 当前有i个吸血鬼,达到目标状态的期望值
则 dp[i] = C(1, i) * C(1, n - i) / C(2, n) * (p * dp[i+1] + (1-p)*dp[i]) + (1 - C(1, i) * C(1, n - i) / C(2, n)) * dp[i] + 1;
化简以后得 dp[i] = dp[i + 1] + (n - 1) * n / (2 * p * i * (n - i))
/************************************************************************* > File Name: zoj3551.cpp > Author: ALex > Mail: [email protected] > Created Time: 2014年12月22日 星期一 20时44分55秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 100010; double dp[N]; double p; int n; double dfs(int i) { if (i == n) { return 0; } if (dp[i] != -1) { return dp[i]; } double pr = (double)n * (n - 1); pr /= (double)2 * p * i * (n - i); // printf("%f\n", pr); dp[i] = dfs(i + 1) + pr; return dp[i]; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%lf", &n, &p); for (int i = 0; i<= n; ++i) { dp[i] = -1; } dp[n] = 0.0; printf("%.3f\n", dfs(1)); } return 0; }