题意:n个人,给出每个人买东西的概率,计算出在有r个人买东西的情况下,每个人买东西的概率。

题解:简单的条件概率,P(A|B)=P(AB)/P(B),这里P(B)就是有r个人买东西的概率,P(AB)是r个人购买并且其中i购买的概率。

dfs以条件判断结束并用pre数组记录路径即可。

#include<algorithm>
#include <iostream>
#include  <cstdlib>
#include  <cstring>
#include  <cassert>
#include   <cstdio>
#include   <vector>
#include   <string>
#include    <cmath>
#include    <queue>
#include    <stack>
#include      <set>
#include      <map>
using namespace std;
#define P(a,b,c) make_pair(a,make_pair(b,c))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef pair<int,pair<int,int> >pii;
typedef long long ll;
const ll mod = 1000000007;
const int INF = 0x3f3f3f3f;
ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
int r,n;
const int maxn = 1e6+5;
double a[100];
double b[100];
double sum=0;
int pre[100];
double s[100];
void C(double ans,int cnt,int k,int next){
	
	if(n==cnt){
		if(r==k){
			sum+=ans;
			while(next){
				s[next]+=ans;
				next=pre[next];
				
			}
		}
		return;
	}
	pre[cnt+1]=next;
	C(ans*a[cnt+1],cnt+1,k+1,cnt+1);
	pre[cnt+1]=0;
	C(ans*b[cnt+1],cnt+1,k,next);
}

int main(){
	int t=0;
	while(scanf("%d%d", &n,&r)==2){
		if(n==0&&r==0)break;
		CLR(pre);
		CLR(s);
		sum=0;
		rep(i,1,n){
			cin>>a[i];
			b[i]=1.0-a[i];
		}
		C(1.0,0,0,0);
		printf("Case %d:\n", ++t);
		rep(i,1,n){
			printf("%.6f", s[i]/sum);
			printf("\n");
		}
	}
	return 0;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注