(LightOJ - 1030)Discovering Gold(概率DP)

本文介绍了LightOJ1030题目Discovering Gold的解题思路,这是一个关于概率和动态规划的问题。玩家在黄金走廊中根据掷骰子移动,求解收集黄金的预期数量。通过建立概率的动态规划模型,计算每个位置经过的概率,并乘以相应位置的黄金数求和,得出答案。提供的C++代码展示了实现过程。
摘要由CSDN通过智能技术生成

题目链接:Discovering Gold - LightOJ 1030 - Virtual Judge (ppsucxtt.cn)

题意:现在有一个长度为n的黄金走廊,你可以把他理解为一个1 * n的序列。每一个位置都可以含有一定数量的黄金。最初你处于位置1。现在每个回合你掷一个6面骰子。假设掷出的数字为X,这时你的位置就会加上X,然后从新的位置收集黄金。如果当前位置加上X后的位置超出了n,则重新掷直到不超过n。当你到达第n个位置时,你就停止了你的旅程。现在已知序列,请你计算你可以收集到的黄金的预期数量。

分析:如果我们能求出经过每个位置的概率,那我们就可以直接把每个位置的概率乘以其位置上的黄金,然后总和即为收集到的黄金的期望。相信大家之前在做dp问题的时候都遇到过爬楼梯问题,每次可以爬一阶或两阶楼梯,问到达第n阶楼梯的方案数一共有多少种,这就是一个典型的dp问题,dp方程是f[n]=f[n-1]+f[n-2],而这道题就是一个对概率的dp,我们如果到达了位置i,那么所有他能到达的位置的概率都要因为他而加上1/p[i],因为他到达他所能到达的每一个位置的概率是相等的,由这个dp方程,我们就可以求得经过每一个点的概率,最后把每个点的概率乘以该点所含的黄金数量相加就得到答案了。

下面是代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int N=105;
double p[N];
int a[N];
int main()
{
	int T;
	cin>>T;
	for(int o=1;o<=T;o++)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			p[i]=0;
		}
		p[1]=1;
		//用当前点的概率去更新它可以到达的点的概率
		for(int i=1;i<n;i++)
		{
			int k=min(6,n-i);
			for(int j=1;j<=k;j++)
				p[i+j]+=p[i]/k;
		}
		double ans=0;
		for(int i=1;i<=n;i++)
			ans+=p[i]*a[i];
		printf("Case %d: %.10f\n",o,ans);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值