LightOJ 1030 Discovering Gold 数学期望计算
题目大意:给出长度为n的一条隧道,每个位置都有一定数量的财宝。给你一枚骰子,roll到几点就前进几步,如果即将到达的地方超过了这条隧道长度,就重新roll一次,走到n点结束。求这个过程能收获多少财宝。
题目思路:很明显问题是求期望值的。
期望值公式:
E(X) = X1*p(X1) + X2*p(X2) + …… + Xn*p(Xn) (p为概率,x为某一点价值)。
具体看代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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\n",cnt++,ans); } return 0; }