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
",ans-dp[19]);//sub ans dp[19] 只要有个账号达到20就好了
23     }
24     //cout << "Hello world!" << endl;
25     return 0;
26 }
View Code
在一个谎言的国度,沉默就是英雄
原文地址:https://www.cnblogs.com/EdsonLin/p/5329713.html