您的位置:首页 > 其它

hdu 4465 求期望

2014-10-29 21:54 239 查看

Candy

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2104 Accepted Submission(s): 904

Special Judge


[align=left]Problem Description[/align]
LazyChild is a lazy child who likes candy very much. Despite being very young, he has two large candy boxes, each contains n candies initially. Everyday he chooses one box and open it. He chooses the first box with probability p and
the second box with probability (1 - p). For the chosen box, if there are still candies in it, he eats one of them; otherwise, he will be sad and then open the other box.

He has been eating one candy a day for several days. But one day, when opening a box, he finds no candy left. Before opening the other box, he wants to know the expected number of candies left in the other box. Can you help him?

[align=left]Input[/align]
There are several test cases.

For each test case, there is a single line containing an integer n (1 ≤ n ≤ 2 × 105) and a real number p (0 ≤ p ≤ 1, with 6 digits after the decimal).

Input is terminated by EOF.

[align=left]Output[/align]
For each test case, output one line “Case X: Y” where X is the test case number (starting from 1) and Y is a real number indicating the desired answer.

Any answer with an absolute error less than or equal to 10-4 would be accepted.

[align=left]Sample Input[/align]

10 0.400000
100 0.500000
124 0.432650
325 0.325100
532 0.487520
2276 0.720000


[align=left]Sample Output[/align]

Case 1: 3.528175
Case 2: 10.326044
Case 3: 28.861945
Case 4: 167.965476
Case 5: 32.601816
Case 6: 1390.500000


[align=left]Source[/align]
2012 Asia Chengdu Regional Contest



//ans=(n-k)C(n+k,k)( p^(n+1)*q^k + q^(n+1)*p^k )
#include<stdio.h>
#include<math.h>
int main()
{
int n,i,cnt=1,num;
double p,cp,cq,ans,q;
while(scanf("%d%lf",&n,&p)!=EOF)
{
q=1-p;
num=n+1;//最后一次一定要拿空的,不要忘记再乘一次概率
cp=cq=1; ans=0;
for(i=0;i<=n;i++)
{
if(i!=0)
{
cp=cp*q*(n+i)/i;//每次组合数可以由前一个数*(n+i)/i得到
cq=cq*p*(n+i)/i;
while(cp>=n||cq>=n)//为了防止数的范围超过double,当数大于n时
{//(因为最终结果不可能大于n)乘以概率来减小,记录乘了多少次概率,最后算的时候少乘
cp*=p;
cq*=q;
num--;//记录需要乘几次概率
}
}
ans+=cp*(n-i)*pow(p,num);
ans+=cq*(n-i)*pow(q,num);
}
printf("Case %d: %lf\n",cnt++,ans);
}
return 0;
}


/*很明显,200000太大了,不能直接排列组合。
然后需要一个快速排列组合函数:logC(m,n)
f[0]=0;
for(int i=1;i<=400002;i++) f[i]=f[i-1]+log(i*1.0);
double logC(int m,int n){
return f[m]-f
-f[m-n];
}
有了上面的算式之后,C(m,n)=exp(logC(m,n))
再对整个式子直接全部取log就行啦*/
#include<stdio.h>
#include<math.h>
#define N 400005
double a
;
double logc(int n,int m)
{
return a
-a[m]-a[n-m];
}
int main()
{
int i,k,n,cnt=1;
double p,q,ans;
a[1]=log(1.0);
for(i=2;i<=400000;i++)
a[i]=a[i-1]+log(i*1.0);
while(scanf("%d%lf",&n,&p)!=EOF)
{
q=1-p; ans=0;
for(k=0;k<=n;k++)
{
ans+=(n-k)*exp((n+1)*log(p)+k*log(q)+logc(n+k,k));
ans+=(n-k)*exp((n+1)*log(q)+k*log(p)+logc(n+k,k));
}
printf("Case %d: %lf\n",cnt++,ans);
}
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: