Discovering Gold LightOJ - 1030(概率DP)

26 篇文章 2 订阅
13 篇文章 2 订阅

题目链接:

Discovering Gold

LightOJ - 1030

题目描述:

有 n 堆金矿,位置为 1 - n 上,告诉你了每个位置金矿的数目 a [ i ] 。现在让你从 1 这个点开始挖金矿,下一个你要去的点通过掷骰子来决定,就是当前位置坐标+骰子数(骰子数:1 - 6),为你挖到金矿数目的期望。

解题思路:

因为起点一定要从 1 开始,所以应该倒着推才能保证从 1 这个点开始挖(最后输出的也是 dp[1])。
对于第 i 个点 ,他的期望值是: dp[i] = dp[ i + 1 ] * 1/6 + dp[ i + 2 ] * 1/6 + ··· + dp[ i + 6 ] * 1/6 +  arr[ i ](当 i + 6 <= n 时),这个递推式的语义就是:我当前挖的矿,的期望是:某一堆可能能转移过来的金矿数目 乘以 某一堆可能能转移过来的概率 之和 + 当前位置的金矿数目。

需要注意的是如果当 i + 6 > n 时:

t = n - i;
dp[i] = dp[ i + 1 ] * 1 / t + dp[ i + 2 ] * 1 / t + ··· + dp[ i + t ] * 1 / t +  arr[ i ];

总起来就是:
t = min(n - i, 6);
dp[i] = dp[ i + 1 ] * 1 / t + dp[ i + 2 ] * 1 / t + ··· + dp[ i + t ] * 1 / t +  arr[ i ];

AC代码:

#include<bits/stdc++.h>
#define up(i, x, y) for(int i = x; i <= y; i++)
#define down(i, x, y) for(int i = x; i >= y; i--)
#define maxn ((int)1e3 + 10)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
double dp[maxn];
int arr[maxn];
int main()
{
    int len = 0;
    int T; scanf("%d", &T); while(T--)
    {

        int n; scanf("%d", &n);
        for(int i = 1; i <= n; i++)
        {
            int x; scanf("%d", &x);
            arr[i] = x;
        }
        dp[n] = arr[n];
        for(int i = n - 1; i >= 1; i--)
        {
            dp[i] = arr[i];
            int x = min(n - i, 6);
            for(int j = 1; j <= x; j++)
            {
                dp[i] += dp[i + j] / x;
            }
        }
        printf("Case %d: %.6f\n",++len, dp[1]);
    }
}

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值