题意: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;
}