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