1. 程式人生 > >「UVA11181」 Probability|Given(概率

「UVA11181」 Probability|Given(概率

表示 之前 badge copy 組合 否則 事件 col block

題意翻譯

有n個人要去買東西,他們去買東西的概率為p[i]。

現在得知有r個人買了東西,在這種條件下,求每個人買東西的概率。

感謝@s_r_f 提供翻譯

題目描述

PDF

技術分享圖片

輸入輸出格式

輸入格式:

技術分享圖片

輸出格式:

技術分享圖片

輸入輸出樣例

輸入樣例#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 }

「UVA11181」 Probability|Given(概率