UVA 11181 Probability|Given dfs模拟组合情况(周赛F题)

来源:互联网 发布:购物软件大全 编辑:程序博客网 时间:2024/06/10 07:47

条件模拟,这题纠结了好久,题目本身就看了好久才理解题意……

题目大意:有n个人去超市买东西,给出r,每个人买东西的概率是p[i],求:当有r个人买东西的时候,第i个人恰好买东西的概率。

例如:

3 2
0.10
0.20
0.30
有两个人是一定买东西的,但是不知道是哪两个。所以情况有:
(1)第一个人和第二个人买,第三个人不买(即(1,1,0)),则概率:0.10*0.20*(1-0.30)=0.014;
(2)第一个人和第三个人买,第二个人不买(即(1,0,1)),则概率:0.10*(1-0.20)*0.30=0.024
(3)个人和第三个人买,第一个人不买(即(0,1,1)),则概率:(1-0.10)*0.20*0.30=0.054。  
则这三个人买的总概率为:0.014+0.024+0.054=0.092;
第一个人买的概率为:0.014+0.024=0.038;
第二个人买的概率为:0.014+0.054=0.068;
第三个人买的概率为:0.024+0.054=0.078。
则第一个人买的条件概率为:0.038/0.092=0.413043;
则第一个人买的条件概率为:0.068/0.092=0.739130;
则第一个人买的条件概率为:0.078/0.092=0.847826;
dfs可以模拟组合的情况:代码如下:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<cmath>#include<set>#include<vector>#include<stack>#define mem(a,b) memset(a,b,sizeof(a))using namespace std;double p[23],pi[23],sum;int n,r,vis[23];void dfs(int st, int t){    int i;    double pn;    if(t==r)    {        pn=1.0;        for(i=1; i<=n; i++)        {            if(vis[i]) pn*=p[i];            else pn*=(1-p[i]);        }        for(i=1; i<=n; i++)            if(vis[i]) pi[i]+=pn;        sum+=pn;        return ;    }    for(i=st; i<=n; i++)    {        vis[i]=1;        dfs(i+1,t+1);        vis[i]=0;    }}int main(){    int i,k=1;    while(scanf("%d%d",&n,&r)&&(n||r))    {        for(i=1; i<=n; i++)            scanf("%lf",&p[i]);        mem(pi,0);        mem(vis,0);        sum=0;        dfs(1,0);        printf("Case %d:\n",k++);        for(i=1; i<=n; i++)            printf("%.6f\n",pi[i]/sum);    }    return 0;}


原创粉丝点击