概率专题 dp概率正推+期望逆推

博客给出题目链接,题目是n个格子,每个格子有值,从1开始扔6面骰子,按点数前进拿金子,若超出n则重扔,求取走值的期望值。指出结局一定的事件概率正推、期望逆推,一个格子可由前6个格子转移而来,还提及概率dp和期望dp。

题目链接:https://vjudge.net/contest/299639#problem/B
题目大意:
n个格子,每个格子有一个值。从1开始,每次扔6个面的骰子,扔出几点就往前几步,然后把那个格子的金子拿走;如果扔出的骰子+所在位置>n,就重新扔,直到在n;问取走这些值的期望值是多少;

这种结局一定的事件:概率只能正推,期望只能逆推。

一个格子可以由前面6个格子转移而来。

概率dp:

//dp[i]途中经过i格子的概率
//期望值=∑(dp[i]*a[i])

#include<bits/stdc++.h>
#define LL long long
using namespace std;

double dp[103];
double a[105];
int main()
{
    int t, CUT=0;
    scanf("%d",&t);
    while(t--)
    {
        CUT++;
        int n;
        double ans=0;
        memset(dp, 0, sizeof(dp));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lf",&a[i]);
        }
        dp[1]=1;
        for(int i=1;i<=n;i++)
        {
            int cut=min(n-i, 6);
            for(int j=1;j<=cut;j++)
            {
                dp[i+j]+=dp[i]*(1.0/cut);
            }
            ans+=dp[i]*a[i];
        }

        printf("Case %d: %.7f\n",CUT, ans);
    }

    return 0;
}

期望dp:

//dp[k]为到达k这个位置时得到金币的期望
//因为结果一定所以从n推到1
//期望值=dp[1]
#include<bits/stdc++.h>
#define LL long long
using namespace std;

double dp[105];
int main()
{
    int t, CUT=0;
    scanf("%d",&t);
    while(t--)
    {
        CUT++;
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lf",&dp[i]);
        }
        int cut=1;
        for(int i=n-1;i>=1;i--)
        {
            cut=min(6, cut);
            for(int j=1;j<=cut;j++)
            {
                dp[i]+=dp[i+j]*(1.0)/cut;
            }
            cut++;
        }
        printf("Case %d: %.7f\n",CUT, dp[1]);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值