「UVA11181」 Probability|Given(概率
题意翻译
有n个人要去买东西,他们去买东西的概率为p[i]。
现在得知有r个人买了东西,在这种条件下,求每个人买东西的概率。
感谢@s_r_f 提供翻译
题目描述
输入输出格式
输入格式:
输出格式:
输入输出样例
输入样例#1: 复制
3 2 0.10 0.20 0.30 5 1 0.10 0.10 0.10 0.10 0.10 0 0
输出样例#1: 复制
Case 1: 0.413043 0.739130 0.847826 Case 2: 0.200000 0.200000 0.200000 0.200000 0.200000
题解
这个题面在讲什么鬼话?!!!(气哭
设$E$表示事件"有$r$个人买了东西",$E_i$表示事件"第$i$个人买了东西".
则根据公式,$P(E_i|E)=P({E_i}E)/P(E)$.
问题转化为求$P(E)$和求$P({E_i}E)$.
对于$P(E)$,用$dfs$枚举每个人买了与否.
设$dfs$到了第$i$个人,在它之前的人买与否构成的组合的概率为$now$,
那么若第$i$个人买,概率为$now*p[i]$,否则为$now*(1-p[i])$.
递推下去就好了.
当$dfs$到了第$n$个人,且正好有$r$个人买了,
那么$P(E)+=now$.
然后就是求$P({E_i}E)$了.
其实也差不多,只是多了一个"第$i$个人必须买"的限制,所以在$dfs$的时候强制第$i$个人买就行了.
1 qwerta 2 UVA11181 Probability|Given Accepted 3 代码 C++,0.79KB 4 提交时间 2018-10-26 18:50:22 5 耗时/内存 200ms, 0KB 6 7 #include<iostream> 8 #include<cstdio> 9 using namespace std; 10 double p[23]; 11 double pe; 12 int n,r; 13 void dfs(int x,int d,double now) 14 { 15 if(d>r)return; 16 if(x==n+1) 17 { 18 if(d==r) 19 pe+=now; 20 return; 21 } 22 //mark 23 dfs(x+1,d+1,now*p[x]); 24 //dismark 25 dfs(x+1,d,now*(1-p[x])); 26 return; 27 } 28 double pei; 29 void dfss(int x,int d,int i,double now) 30 { 31 if(d>r)return; 32 if(x==n+1) 33 { 34 if(d==r) 35 pei+=now; 36 return; 37 } 38 if(x==i) 39 {dfss(x+1,d+1,i,now*p[x]);return;} 40 //mark 41 dfss(x+1,d+1,i,now*p[x]); 42 //dismark 43 dfss(x+1,d,i,now*(1-p[x])); 44 return; 45 } 46 int main() 47 { 48 ios::sync_with_stdio(false); 49 int tim=0; 50 while(cin>>n>>r) 51 { 52 if(n==0)break; 53 printf("Case %d:\n",++tim); 54 for(int i=1;i<=n;++i) 55 cin>>p[i]; 56 pe=0; 57 dfs(1,0,1); 58 for(int i=1;i<=n;++i) 59 { 60 pei=0; 61 dfss(1,0,i,1); 62 printf("%.6f\n",pei/pe); 63 } 64 } 65 return 0; 66 }