Probability|Given【条件概率】

传送门
“r个人买了东西”这个事件叫E,“第i个人买东西”这个事件为Ei,则要求的是条件概 率P(Ei|E)。根据条件概率公式, P ( E i ∣ E ) = P ( E i E ) / P ( E ) P(Ei|E) = P(EiE) / P(E) P(EiE)=P(EiE)/P(E)
P(E)依然可以用全概率公式。例如, n = 4 , r = 2 n=4,r=2 n=4r=2,有6种可能: 1100 , 1010 , 1001 , 0110 , 0101 , 0011 , 1100, 1010, 1001, 0110, 0101, 0011, 1100,1010,1001,0110,0101,0011其中1100的概率为 P 1 ∗ P 2 ∗ ( 1 − P 3 ) ∗ ( 1 − P 4 ) P1*P2*(1-P3)*(1-P4) P1P2(1P3)(1P4),其他类似,设置 A [ k ] A[k] A[k]表示第k个人是否买 东西(1表示买,0表示不买),则可以用递归的方法枚举恰好有r个A[k]=1的情况。
如何计算 P ( E i E ) P(EiE) P(EiE)呢?方法一样,只是枚举的时候要保证第A[i]=1。不难发现,其实可以 用一次枚举就计算出所有的值。用tot表示上述概率之和, s u m [ i ] sum[i] sum[i]表示 A [ i ] = 1 A[i]=1 A[i]=1的概率之和.
则答 案为 P ( E i ) / P ( E ) = s u m [ i ] / t o t P(Ei)/P(E)=sum[i]/tot P(Ei)/P(E)=sum[i]/tot
code:

#include
#include
using namespace std; 
const int N=25;
int n,buy[N],r;
double P[N],sum[N];

void dfs(int d,int c,double pro){
	if(c>r||d-c>n-r) return;
	if(d==n){
		sum[n]+=pro;
		for(int i=0;i<n;i++)
			if(buy[i]) sum[i]+=pro;
		return;
	}
	buy[d]=0;
	dfs(d+1,c,pro*(1-P[d]));
	buy[d]=1;
	dfs(d+1,c+1,pro*P[d]);
} 

int main(){
	int kase=0;
	while(cin>>n>>r,n){
		for(int i=0;i<n;i++)
			cin>>P[i];
		memset(sum,0,sizeof(sum));
		dfs(0,0,1.0);
		printf("Case %d:\n", ++kase);
   		 for(int i = 0; i < n; i++)
      	printf("%.6lf\n", sum[i] / sum[n]);
	}
}

你可能感兴趣的:(概率,条件概率,数论)