题目要求条件概率,用贝叶斯公式我们很容易得到我们需要求r个人买东西的概率和每个人买东西的条件下其他r-1个人买东西的概率.我们递归枚举,每当枚举到r个人买东西的时候,我们加入到r个人买东西的概率中(全概率公式),然后对于这r个人,除去自己买东西的概率就是其他r-1个人买东西的概率(当然不是全部,加上就可以了).因此一遍枚举就可以了.
记得不买东西也是有概率的
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
#include<cctype>
#include<queue>
#include<set>using namespace std;typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=25;int n,r;
double p[MAXN];
bool vis[MAXN];
double sum[MAXN];
double tot;void dfs(int cur,int left)
{if(left==0){double tmp=1.0;for(int i=1;i<=n;i++){if(vis[i]){tmp*=p[i];}else{tmp*=(1-p[i]);}}tot+=tmp;for(int i=1;i<=n;i++){if(vis[i]){sum[i]+=tmp/p[i];}}return;}for(int i=cur;i<=n;i++){if(n-i+1<left) return;vis[i]=true;dfs(i+1,left-1);vis[i]=false;}
}int main()
{int Case=0;while(~scanf("%d%d",&n,&r) && (n||r)){for(int i=1;i<=n;i++)scanf("%lf",&p[i]);memset(vis,0,sizeof(vis));memset(sum,0,sizeof(sum));tot=0;dfs(1,r);printf("Case %d:\n",++Case);for(int i=1;i<=n;i++){printf("%.6f\n",sum[i]*p[i]/tot);}}return 0;
}