LightOJ 1030 Discovering Gold 数学期望计算

题目大意:给出长度为n的一条隧道,每个位置都有一定数量的财宝。给你一枚骰子,roll到几点就前进几步,如果即将到达的地方超过了这条隧道长度,就重新roll一次,走到n点结束。求这个过程能收获多少财宝。

题目思路:很明显问题是求期望值的。

期望值公式:

E(X) = X1*p(X1) + X2*p(X2) + …… + Xn*p(Xn) (p为概率,x为某一点价值)。

具体看代码

#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 1000005
#define mod 1000000007

using namespace std;

double Toss[MAX];//到达某一点的概率
int val[MAX];

double Roll(int n)
{
    if(n==1)
        return val[1]*1.0;
    int i,j;
    double sum=0,k;
    sum=val[1]+val[n];//1点和n点必定到达
    memset(Toss,0,sizeof(Toss));
    Toss[1]=1;
    for(i=1;i<n;i++)
    {
        int d=n-i;//距离终点的距离
        if(d<6)//如果小于6,那么从当前点到达剩余点的概率为1/d;
        {
            k=1.0/(d*1.0);
            for(j=1;j<=d;j++)
            {
                Toss[i+j]=Toss[i+j]+(Toss[i]*k);//更新到达i+j点的概率
            }
        }

        else//如果大于6,那么从当前点到达剩余点的概率为1/6;
        {
            k=1.0/6;
            for(j=1;j<=6;j++)
            {
                Toss[i+j]=Toss[i+j]+(Toss[i]*k);
            }
        }
    }
    for(i=2;i<n;i++)//计算期望值
    {
        sum+=(Toss[i]*val[i]);
    }
    return sum;
}

int main()
{
    int T,i,n,cnt=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&val[i]);
        memset(Toss,0,sizeof(Toss));
        double ans=Roll(n);
        printf("Case %d: %.6lf
",cnt++,ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/alan-W/p/5785174.html