zoukankan      html  css  js  c++  java
  • 题解-概率计算器

    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 xcdot dx ]

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

    (f(x)=p(ansleq x)),则有(f'(x)=p(ans=x))

    即最终答案为

    [int_0^1f'(x)cdot xcdot 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
    ",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;
    	}
    }
    
  • 相关阅读:
    mysql参数优化
    看见的一个mysql面试题
    面向对象的继承
    面向对象的权限修饰符
    php实现无限极分类
    php的冒泡排序
    frame框架的跳转
    thinkphp中open路径问题
    mysql触发器
    mysql事务
  • 原文地址:https://www.cnblogs.com/penth/p/9675816.html
Copyright © 2011-2022 走看看