Rating(概率DP) HDU - 4870

题目

  https://cn.vjudge.net/problem/HDU-4870

题意

  一人用两个账号参加比赛,每次只会用分数较少的账号去参加。取胜加50分,落败扣100分但最多为0分。现在两个账号都为0分,给出取胜的概率p,问要参加多少场比赛能使其中一个账号到达1000分的期望。

思路

  我们令dp【i】表示从(i - 1)* 50 到 i * 50 分的期望场数,(dp【1】表示 0 ~ 50 分的期望场数)。那么这时候分为赢和输两种情况,赢的话明显状态转移 dp【i】= 1 * p。输了的话就要从dp【i - 2】的位置从新起步,所以转移为dp【i】= (1 - p)* (1 + dp【i - 2】+ dp【i - 1】+ dp【i】)(1表示输了走的那一步)。那么总的转移也就是dp【i】= p + (1 - p)*(1 + dp【i - 2】+ dp【i - 1】+ dp【i】)。

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <stack>
#include <map>
#define ull unsigned long long
#define met(a, b) memset(a, b, sizeof(a))
#define lowbit(x) (x&(-x))
#define MID (l + r) / 2
#define ll long long

using namespace std;

const int maxn = 1e5 + 7;
const ll mod = 1e6 + 3;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;

double dp[30];

int main() {
    double p;
    while(cin >> p) {
        double sum = 0;
    //预处理 0 和 1 位置的dp值 dp[
0] = 1/p; dp[1] = (1 + (1 - p) * dp[0]) / p; sum = dp[0] + dp[1]; for(int i = 2; i <= 19; i++) { dp[i] = (1 + (1 - p) * (dp[i-2] + dp[i-1])) / p; sum += dp[i]; } printf("%.6lf\n", sum+sum-dp[19]); 最后其实两个账号一个为1000分,另一个是950分,所以减去dp【19】。 } return 0; }

 

posted @ 2019-08-12 09:03  Ruby·Z  阅读(218)  评论(0编辑  收藏  举报