hdu 4870 Rating(概率dp)

题意:给你两个初始分数为0的账号让你去打比赛,每场比赛赢的概率为p,赢了加50分,输了-100分,当然你不会负分,每次你会用分低的账号去打比赛,问你把一个账号打到1000分的需要参加比赛次数的期望值。

 

思路:网上都是说理所当然,反正这是我做的第二道概率dp我是想不出来,写这个博客是因为别人都没说清楚,我都不知道咋化简的,搞明白后我来写个详细的。

把50分当成1分,赢一把加1分数了-2。dp【i】存的是从i-1分升到i分需要参加比赛次数的期望。如果赢的话,也就是打一场就到了,输的话分数变成了i-3,还得需要1 + dp[i-2] + dp[i-1] + dp[i]次才能到i分,因为就算输了,也是算参加了一次的,所以有这个1。 得到dp[i] = p*1 + (1-p)*(1 + dp[i-2] + dp[i-1] + dp[i]); 把右边的dp[i]移项化简:dp[i] = 1/p + (1-p)/p*(dp[i-2] + dp[i-1]); 只用算出来dp[1] dp[2]就行了,dp[1]很明显是1/p, dp[2]和dp[i]差不多,但是分不会降到负数只会降到0。dp[2] = p*1 + (1-p)*(1+dp[1]+dp[2]), 化简就是dp[2] = 1/p/p;

因为每次会打分第的号,所以结果肯定是一个1000分,一个950分,算出来两个都到1000分需要参加的场次,减去一个950分到1000分需要参加的场数就行了,也就是一个分数到1000一个到950需要的场次。

#include <bits/stdc++.h>
using namespace std;

double dp[25]; //dp[i] 存的是从i-1涨分到i所需要参加比赛次数的期望
int main()
{
    double p, tot;
    while(cin >> p){
        dp[1] = 1/p;
        dp[2] = 1/p + (1-p)/p*dp[1];
        tot = dp[1] + dp[2];
        for(int i = 3; i <= 20; i++){
            dp[i] = 1/p + (1-p)/p*(dp[i-2] + dp[i-1]);
            tot += dp[i];
        }
        printf("%.6lf\n",tot*2 - dp[20]);
    }
    return 0;
}

 

posted @ 2019-08-10 10:19  philo_zhou  阅读(196)  评论(0编辑  收藏  举报