Description
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.
Input
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.
Output
For each case, you should output the expectation(3 digits after the decimal point) in a single line.
題意:
有N個村民,其中1個是吸血鬼,每天都有恰好兩個村民互相碰面,如果碰面的是吸血鬼和正常人,則有p的概率讓後者變爲吸血鬼,問全部村民變成吸血鬼的期望天數。
範圍:
N<=10w
解法:
很明顯的概率DP,設DP[I]爲I個人變成吸血鬼的期望天數,那麼DP[1]=0,DP[I]=DP[I-1]+ E 其中E是在 I-1個吸血鬼,N-I+1個人中製造出一個吸血鬼的期望天數,可知每一天都有 p*(I-1)*(N-I+1)/ C(2,N)的概率製造出一個吸血鬼,記爲Tp,其滿足幾何分佈,期望爲1/ Tp
代碼:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<bitset>
#pragma comment(linker, "/STACK:1024000000,1024000000")
template <class T>
bool scanff(T &ret){ //Faster Input
char c; int sgn; T bit=0.1;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
if(c==' '||c=='\n'){ ret*=sgn; return 1; }
while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
ret*=sgn;
return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
double dp[100100];
int main(){
tdata{
int n;
double p;
scanff(n);
scanff(p);
dp[1]=0.0;
double tot=double(n)*double(n-1)/2.0;
rep(i,2,n){
double b=double(i-1);
double a=double(n-i+1);
double tp=p*a*b/tot;
dp[i]=dp[i-1]+1/tp;
}
printf("%.3f\n",dp[n]);
}
return 0;
}