您的位置:首页 > 其它

zoj 3329 One Person Game(数学期望)

2012-09-23 01:05 274 查看
题解:

对于期望值,一般定义的Ex都是表示离目标状态还需要的代价
所以这里定义E[i]表示当前状态为i离结束还需要代价的期望值,那答案就是E[0]。

对于期望类问题,一般解法是列出方程式,若状态之间存在环,则可采用高斯消元解方程组,也可想办法消环;反之,则可直接递推来求出目标状态。

对于该题:

E[x] = 0 (x>n);

E[i] = ∑Pk*E[i+k] + P0*E[0] + 1;

设 E[i] = a[i]*E[0] + b[i];

联合上面的式子可消去E[i+k],可得E[i] = ( ∑Pk*a[i+k] + P0 )*E[0] + ∑Pk*b[i+k] + 1;

可得出:
a[i] = ∑Pk*a[i+k] + P0;
b[i] = ∑Pk*b[i+k] + 1;

接下来可求出ai和bi,最后得出E[0] = b[0]/(1-a[0]);

View Code

/*
Author:Zhaofa Fang
PROB:zoj 3329
Lang:C++
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef long long ll;
const int INF = 2147483647;

double e[550];
double p[550];
double x[550];
int a,b,c;
void init(double k1,double k2,double k3)
{
for(int i=0;i<550;i++)p[i]=e[i]=x[i]=0;
for(int i=1;i<=(int)k1;i++)
{
for(int j=1;j<=(int)k2;j++)
{
for(int k=1;k<=(int)k3;k++)
{
if(a!=i || b != j || c != k)
p[i+j+k]+= 1.0/(k1*k2*k3);
}
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif
int T;
cin>>T;
while(T--)
{
int n;
double k1,k2,k3;
scanf("%d%lf%lf%lf",&n,&k1,&k2,&k3);
scanf("%d%d%d",&a,&b,&c);
init(k1,k2,k3);
for(int i=n;i>=0;i--)
{
e[i] = 1/(k1*k2*k3);
x[i] = 1.0;
for(int j=3;j<=(int)(k1+k2+k3);j++)
{
e[i] += p[j]*e[i+j];
x[i] += p[j]*x[i+j];
}
}
printf("%.15f\n",x[0]/(1-e[0]));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: