UVA 11181-Probability|Given
题目原址
[https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2122]
题意
给定 n 个事件以及其发生的概率 p i p_{i} pi ,现在其中同时发生的事件有 r 件,问每件事情是其中一件的概率
题解
条件概率,在 r 发生的条件下每件事发生的概率,
P
(
A
i
∣
B
)
=
P
(
A
i
B
)
P
(
B
)
P(A_{i}|B)=\frac{P(A_{i}B)}{P(B)}
P(Ai∣B)=P(B)P(AiB)然后难点就在于从所有事件中,列举出 r 件事件的组合,求出
P
(
A
i
B
)
,
P
(
B
)
P(A_{i}B),P(B)
P(AiB),P(B)
(原来没想到怎么列举,看了一下别人的题解,后来还是wa了,最后才发现我的Case %d: 后面多了一个空格,pdf里面复制粘贴自动会多带一个空格,被坑了)
代码
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 29;
int n,r;
double p[maxn],ans[maxn];
bool vis[maxn];
void dfs(int k,int cnt){
if(cnt==r){
double tmp=1;
for(int i=1;i<=n;i++)
if(vis[i])
tmp*=p[i];
else
tmp*=1-p[i];
ans[0]+=tmp;
for(int i=1;i<=n;i++)
if(vis[i])
ans[i]+=tmp;
}
else{
for(int i=k+1;i<=n;i++){
vis[i]=true;
dfs(i,cnt+1);//列举所有组合
vis[i]=false;
}
}
}
int main(){
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif // LOCAL
cout<<setprecision(6)<<fixed;
int Case=1;
while(~scanf("%d%d",&n,&r)&&n){
memset(ans,0,sizeof(ans));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
scanf("%lf",&p[i]);
dfs(0,0);
for(int i=0;i<=n;i++)
if(!i)
printf("Case %d:\n",Case++);
else
cout<<ans[i]/ans[0]<<endl;
}
}