码迷,mamicode.com
首页 > 其他好文 > 详细

题解-概率计算器

时间:2018-09-19 18:04:36      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:比较   scan   getc   const   lse   space   names   for   void   

Problem

求给定式子的期望:题面

Solution

由于式子是由\(\max ,\min\)组成的,而这东西是基于比较大小的,所以我们需要想想在基于比较的情况下方便实现的东西

\(f(x)\)表示式子小于等于\(x\)的概率,\(g(x)\)表示式子大于等于\(x\)的概率


则对于单个变量,易证有:

\(f(x)=x\\g(x)=1-f(x)\)

对于式子\(\max(x_1,x_2)\)

\[f(x)=f_1(x)\cdot f_2(x)\]

\[g(x)=1-f_1(x)\cdot f_2(x)\]

对于式子\(\min(x_1,x_2)\)

\[g(x)=g_1(x)\cdot g_2(x)\]

\[f(x)=1-g_1(x)\cdot g_2(x)\]


接下来考虑如何统计答案

众所周知,答案可以表达为

\[\int_0^1p(ans=x)\cdot x\cdot dx\]

由于\(f(x)\)表示的是式子小于等于\(x\)的概率

\(f(x)=p(ans\leq x)\),则有\(f‘(x)=p(ans=x)\)

即最终答案为

\[\int_0^1f‘(x)\cdot x\cdot dx\]

\(f(x)\)可以由递归求解

至于原式的话,只要简单求导积分即可


注意:如果在oj上下了数据,并且在第六位小数处出现1的误差,是因为oj上下载数据的链接有问题?提交即可AC

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rg register

template <typename _Tp> inline _Tp read(_Tp&x){
    char c11=getchar(),ob=0;x=0;
    while(c11^‘-‘&&!isdigit(c11))c11=getchar();if(c11==‘-‘)ob=1,c11=getchar();
    while(isdigit(c11))x=x*10+c11-‘0‘,c11=getchar();if(ob)x=-x;return x;
}

const int N=100;
int l[N],r[N],m[N];
int ps[10101],st[N];
char s[10101];
int n,len;

struct poly{
    ll a[N];int d;
    inline poly(){memset(a,0,sizeof(a)),d=0;}
    friend inline poly operator * (poly A,poly B){
        poly res;res.d=A.d+B.d-1;
        for(rg int i=0;i<A.d;++i)
        for(rg int j=0;j<B.d;++j)
            res.a[i+j]+=A.a[i]*B.a[j];
        return res;
    }
    friend inline poly operator - (poly A,poly B){
        poly res;res.d=max(A.d,B.d);
        for(rg int i=0;i<res.d;++i)
            res.a[i]=A.a[i]-B.a[i];
        return res;
    }
    inline void deri(){
        for(rg int i=0;i<d-1;++i)
            a[i]=a[i+1]*(i+1);
        a[--d]=0;
    }
}ans,vec;

poly calc(int opt,int L,int R){
    if(s[L+1]==‘x‘){
        poly res;res.d=2;
        if(!opt)res.a[1]=1;
        else res.a[1]=-1,res.a[0]=1;
        return res;
    }
    for(int i=L+1;i<=R;++i)if(ps[i]){
        int id=ps[i];
        if(!opt)
            if(s[i-1]==‘x‘)return calc(opt,l[id],m[id])*calc(opt,m[id]+1,r[id]);
            else return vec-(calc(opt^1,l[id],m[id])*calc(opt^1,m[id]+1,r[id]));
        else
            if(s[i-1]==‘n‘)return calc(opt,l[id],m[id])*calc(opt,m[id]+1,r[id]);
            else return vec-(calc(opt^1,l[id],m[id])*calc(opt^1,m[id]+1,r[id]));
    }
}

void init();
int main(){
    vec.d=2;vec.a[0]=1;
    while(~scanf("%s",s)){
        init();
        ans=calc(0,-1,len-1);
        ans.deri();
        for(rg int i=ans.d;i;--i)
            ans.a[i]=ans.a[i-1];
        ans.a[0]=0;++ans.d;
        double res=0;
        for(rg int i=ans.d;i;--i)
            res+=1.0*(ans.a[i-1]%i)/i;
        while(res<=0)++res;while(res>=1)--res;
        printf("%.6lf\n",res);
    }return 0;
}

void init(){
    scanf("%s",s);getchar();
    cin.getline(s,10000);
    len=strlen(s);
    memset(ps,0,sizeof(ps));
    int idc=0,tp=0;
    for(int i=0;i<len;++i){
        if(s[i]==‘(‘)ps[l[st[++tp]=++idc]=i]=idc;
        else if(s[i]==‘,‘)m[st[tp]]=i;
        else if(s[i]==‘)‘)r[st[tp--]]=i;
    }
}

题解-概率计算器

标签:比较   scan   getc   const   lse   space   names   for   void   

原文地址:https://www.cnblogs.com/penth/p/9675816.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!