2018 CCPC吉林站 D - The Moon (概率dp求期望)

在这里插入图片描述
题意:一开始给你一个得到箱子的概率q = 2%,还有一个每局游戏获胜的概率p(输入)。然后按照以下的规则进行游戏:
1.游戏开始,如果玩家赢了走到第2步,否则走到第3步
2.玩家有q的概率得到一个箱子,玩家得到箱子后游戏就会立即结束,如果没有得到箱子,那么q += 2%
3.q += 1.5%
4.回到1,重复上述步骤直到游戏结束。
问你玩家玩到游戏结束,进行局数的期望是多少局?

思路:好像是套路的概率dp题求期望,dp[q]代表当前概率为q时进行游戏局数的期望。我们知道到q的概率达到100%的时候,我们只要赢了游戏那么就一定会结束游戏,也就是说p为100%时,进行局数的期望符合伯努利试验的几何分布的情况(即n次游戏前n-1次都是数的,第n次赢了),套用公式即为 E = 1/p,所以这样我们就可以确定dp[100]的期望了。然后我们逆推公式即可得到dp[2]的期望,也就是题目给出的我们的期望。
这里对于逆推的理解,我觉得可能是因为后面的概率也就是100%概率下,期望值比较好直接确定。

对于概率dp,kaungbin这样说,概率DP主要用于求解期望,概率等题目。转移方程比较灵活。一般求概率正推,求期望是逆推。
一般的DP,dp[x]代表到当前这一下状态x下有多少,而期望dp[x]可以表示为在当前状态x下还差多少到达最终状态。

这道题转移方程dp[i] = p*(1-q)*dp[min(q+2,100)] + (1-p)*dp[min(q+1.5,100)] + 1。1代表当前这一游戏局数,p * (1-q)*dp[min(q+2,100)] 代表有p * (1-q)的概率加上dp[min(q+2,100)] 的局数到达最终的状态,另外一个同理。

ps:因为用数组保存概率不能有小数,所以扩大成整数就可以了。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int eps = 1e-6;
const int MAXN = 1e3+7;
double dp[MAXN];
//这里用数组存一下概率 所以1.5 把它扩大成整数去存
int main()
{
	int T,cas = 0;
	scanf("%d",&T);
	while(T--){
		double p;
		memset(dp,0,sizeof(dp));
		scanf("%lf",&p);
		p /= 100;
		dp[1000] = 1/p;//伯努利实验 几何分布的公式
		//cout<<p<<' '<<dp[1000]<<endl;
		for(int i = 999;i >= 20;i --){//dp[20]也就是初始的q = 2%使我们到达的最终状态
			dp[i] = p*(1.0-(1.0*i)/1000)*dp[min(i+20,1000)] + (1.0-p)*dp[min(i+15,1000)] + 1.0;//1代表我当前的这一局
		}
		printf("Case %d: %.10f\n",++cas,dp[20]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值