式子是很好推的,只是當時不知道如何去控制精度問題。要知道P的N次方是很小的一個數。
最後的式子很簡單的
for(int i=0;i<=n;i++)ans+=(n-i)*C(n+i,i)*(p^n*(1-p)^i + (1-p)^n*p^i);
又可以遞推出C。 C(n+1,i+1)=C(n,i)*(n+1)/(i+1)...
然後因為直接算出P的N次方會很小,所以將這個數分解。分N次乘上去。
#include <iostream> #include <cstdio> #include <cmath> using namespace std; double solve(int n,double p) { double ans=p*n;//因為最後還要去看看第一個箱子,所以最後還是得乘以一個P的 double last=1;//遞推的一個中間變量 for(int i=1;i<=n;i++) { last*=(n+i)*(1-p)/i*p;//因為每個中間式子都要乘以N個P,所以每個新生成的中間式子都要補一個P ans+=last*(n-i); ans*=p; } return ans; } int main() { int n; double p; int CASE=1; while(scanf("%d%lf",&n,&p)!=EOF) { printf("Case %d: %lf\n",CASE++,solve(n,p)+solve(n,1-p)); } return 0; }