2014 Multi-University Training Contest 1.10 hdu4870 dp
这是一道dp题
50,100,150,200,..1000其实是50的倍数,可以看作1,2,3,4...20
两个号每次用最小的一个,一个达到20,另一个肯定是19,同时可以看出这两个账号每次加分所用到的期望场次并没有关系
加分情况:可以看作+1分 min(x+1,20)
减分情况:可以看作-2分,0分和1分特殊,只能减到0,max(x-2,0)
其实不考虑减分的话,就是一道求几何概率期望的题了,每次加1分的所用场次期望为 E£ = 1/p,这是书上给的公式,下面我们用dp的方式推一下
E£ = 1*p + (1-p)(1+E£) //这里的1表示当前所用场次
化简得 E£ = 1/p,可以看出每加一分所用的场次期望都是一样的,
也就是说0到1用的期望场次是1/p,1到2用到的期望场次也是1/p,...
我们可以把0到1的所用的期望场次看作dp[0],1到2所用到的期望场次为dp[1],dp[i]表示i到i+1所用到期望场次
很简单可以推出只考虑一个账号达到i所用的总共的期望场次为
ans = ∑dp[i-1]
本题考虑减分,失败一次,减2分,i=i-2,则如果dp[i]失败,接下来的场次应该从dp[i-2]+dp[i-1]+dp[i]
同几何概率每次成功所用场次的期望推导,我们可以推出
dp[i] = 1*p + (1-p)*(1+dp[i]+dp[i-1]+dp[i-2])
令q = 1-p //失败的概率
化简得 dp[i] = (1+q*(dp[i-2]+dp[i-1]))/p
但是
dp[0]和dp[1]不会到达i-2情况,因为 x = max(x-2,0)
所以dp[0]就是几何概率期望 dp[0]=1/p
dp[1] = 1*p+(1-p)(1+dp[1]+dp[0]) 化简得 dp[1] = 1/p/p
1 //#programming dp 2 3 #include <iostream> 4 #include <cstdio> 5 using namespace std; 6 7 int main() 8 { 9 double dp[20]; 10 double ans=0; 11 double p,q; 12 while(~scanf("%lf",&p)){ 13 q = 1-p; 14 dp[0] = 1./p; 15 dp[1] = 1./p/p; 16 for(int i=2;i<20;i++){ 17 dp[i] = (1+q*(dp[i-2]+dp[i-1]))/p; 18 } 19 ans = 0; 20 for(int i=0;i<20;i++) 21 ans += dp[i]*2; 22 printf("%.6lf\n",ans-dp[19]);//sub ans dp[19] 只要有个账号达到20就好了 23 } 24 //cout << "Hello world!" << endl; 25 return 0; 26 }