原题链接
题目大意
有
n
(
1
≤
n
≤
20
)
n\ (1\le n\le 20)
n (1≤n≤20) 个人去逛商场,第
i
i
i 个人在商场买东西的概率为
p
i
(
0.1
<
p
i
<
1
)
p_i(0.1< p_i<1)
pi(0.1<pi<1)
他们逛完商场后,已知有
r
(
0
≤
r
≤
n
)
r(0\le r\le n)
r(0≤r≤n) 个人买了东西,对每个人求他买了东西的概率。
解题思路
可以利用贝叶斯公式来分析
P
(
A
)
,
P
(
B
)
,
P
(
A
∣
B
)
P(A),P(B),P(A|B)
P(A),P(B),P(A∣B) 之间的关系:
P
(
A
∣
B
)
=
P
(
A
∩
B
)
P
(
B
)
=
P
(
A
)
×
P
(
B
∣
A
)
P
(
B
)
P(A|B )=\frac{P(A\cap B)}{P(B)}=\frac{P(A)\times P(B|A)}{P(B)}
P(A∣B)=P(B)P(A∩B)=P(B)P(A)×P(B∣A)
如何求出这个公式的值?我们考虑使用类似解决背包问题的方法(可能是动规,也有可能是递推,我不知道)
假设
f
i
,
j
f_{i,j}
fi,j 表示前
i
i
i 个人中,
j
j
j 个人进行了购物,那么,可以使用如下的方法进行转移:
f
i
,
j
=
f
i
−
1
,
j
×
(
1
−
p
i
)
+
f
i
−
1
,
j
−
1
×
p
i
f_{i,j}=f_{i-1,j}\times (1-p_i)+f_{i-1,j-1}\times p_i
fi,j=fi−1,j×(1−pi)+fi−1,j−1×pi
也就表示,前
i
i
i 个人中
j
j
j 个人进行购物的概率为:前
i
−
1
i-1
i−1 个人中
j
j
j 个人购物的概率乘上第
i
i
i 个人不购物的概率(
1
−
p
i
1-p_i
1−pi),再加上前
i
−
1
i-1
i−1 个人中
j
−
1
j-1
j−1 个人购物的概率乘上第
i
i
i 个人购物的概率。(特殊情况:当在运算
P
(
第
n
2
个
人
必
须
购
物
∣
一
共
有
n
个
人
购
物
)
P(第n_2个人必须购物|一共有n个人购物)
P(第n2个人必须购物∣一共有n个人购物) 枚举到前
n
2
n_2
n2 个人时,因为最后还需要乘
p
n
2
p_{n_2}
pn2,所以本来
f
i
,
j
=
f
i
−
1
,
j
×
p
n
2
f_{i,j}=f_{i-1,j}\times p_{n_2}
fi,j=fi−1,j×pn2 只需
f
i
,
j
=
f
i
−
1
,
j
f_{i,j}=f_{i-1,j}
fi,j=fi−1,j 即可,至于为什么不用加
f
i
−
1
,
j
−
1
×
p
i
f_{i-1,j-1}\times p_i
fi−1,j−1×pi 是因为这是不购物的概率,而
n
2
n_2
n2 这个人目前的假设是必须购物)
代码实现
#include<bits/stdc++.h>
using namespace std;
int n,r;
double p[100],f[100][100];
double work(int n2)
{//i表示前i个人,j表示有j个人购物
f[0][0]=1;//0个人中0个人购物的概率为1
for(int i=1;i<=n;i++){//枚举前i个人购物
if(i==n2){//必须购物的第n2个人
for(int j=0;j<=min(i,r);j++)//特殊情况
f[i][j]=f[i-1][j];
continue;
}
f[i][0]=f[i-1][0]*(1-p[i]);//若j=0还j-1就会RE
for(int j=1;j<=min(i,r);j++)//转移方程
f[i][j]=f[i-1][j]*(1-p[i])+f[i-1][j-1]*p[i];
}
if(n2==0)//当规定第0个人必须购物时,默认为求事件B的概率(所有人中有r个人购物的概率)
return f[n][r];
return f[n][r-1];//由于规定了第n2个人必须购物,只需要求出所有人中r-1个人购物的概率即可
}
int main()
{
cin>>n>>r;
for(int i=1;i<=n;i++){
cin>>p[i];
p[i]=p[i]/100.0;//给定的概率是按照百分比的形式给出的,所以需要除以100
}
double B=work(0);//求出事件B的概率
for(int i=1;i<=n;i++)//求出第i个人购物的概率
cout<<work(i)*p[i]/B<<" ";
return 0;
}
样例
输入
3 2
10 20 30
输出
0.413043 0.739130 0.847826
注意:要求:用户输出与标准输出的绝对误差不超过1e-3