The Moon(概率dp)

前言

这道题是2018年CCPC吉林赛区的C题,是一道铜牌的dp题目。

题意

玩一个游戏,开始有一个概率 q = 2 % q = 2\% q=2%,然后给定概率 p % p\% p%。每一轮游戏,获胜概率是 p % p\% p%,如果没获胜,则 q = q + 1.5 % q=q+1.5\% q=q+1.5%,继续游戏。如果获胜,则进行抽奖,抽中的概率是 q % q\% q%,如果抽中游戏停止;如果没抽中,则 q = q + 2 % q=q+2\% q=q+2%,继续游戏。求游戏进行轮数的期望。

思路

概率dp的一种常用方法是从状态机的角度去考虑。 f ( i ) f(i) f(i)表示起始抽中概率是 i / 100 i/100 i/100时,轮数的期望值。下面进行分类讨论。
如果这一轮游戏获胜,则分为两种情况考虑。如果抽奖抽中了,那么游戏终止,轮数不增加,状态转移方程为 f ( i ) = p ∗ ( i / 100 ) f(i) = p*(i/100) f(i)=p(i/100);如果没抽中,那么游戏轮数加一,进入到下一个状态,转移方程为 f ( i ) = p ∗ ( 1 − i / 100 ) ∗ f ( m i n ( i + 2 , 100 ) ) f(i) = p*(1-i/100)*f(min(i+2,100)) f(i)=p(1i/100)f(min(i+2,100))
如果这一轮游戏未获胜,那么直接进入下一轮,状态转移方程为 f ( i ) = ( 1 − p ) ∗ ( 1 + f ( m i n ( i + 1.5 ) , 100 ) ) f(i) = (1-p)*(1+f(min(i+1.5),100)) f(i)=(1p)(1+f(min(i+1.5),100))
状态转移方程有了之后,我们再考虑初始状态,如果一开始 q = 100 % q = 100\% q=100%,那么只要获胜就直接停止,所以问题转化为了一个超几何分布,期望为 1 / p 1/p 1/p
逆序推一遍后, f ( 2 ) f(2) f(2)即为所求。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

const int N = 1010;

double f[N];

int main()
{
    int T;
    scanf("%d",&T);
    int cas = 0;
    while(T--){
        double p;
        scanf("%lf",&p);
        p /= 100;
        f[1000] = 1 / p;
        for(int i=999;i>=2;i--){
            f[i] = p * (i / 1000.0 + (1 - i / 1000.0) * (1 + f[min(i + 20, 1000)]));
            f[i] += (1 - p) * (1 + f[min(i + 15, 1000)]);
        }
        printf("Case %d: %.10f\n",++cas,f[20]);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值