刷题记录:P8804 [蓝桥杯 2022 国 B] 故障 条件概率

传送门:洛谷

题目描述:

题目较长,此处省略
输入:
3 5
30 20 50
0 50 33 25 0
30 0 35 0 0
0 0 0 25 60
1
3
输出:
2 56.89
1 43.11
3 0.00

读完题目,我们会发现其实题目给了我们两个事件,并且这两个事件是相互关联的.因此不难想到使用条件概率

我们将故障原因看做事件 A A A,结合题意,我们共有 A 1 , A 2 , A 3... A n A1,A2,A3...An A1,A2,A3...An
将故障现象看做事件 B B B,我们共有 B 1 , B 2 , B 3... B M B1,B2,B3...BM B1,B2,B3...BM
此时事件A是事件B的条件,事件B是事件A的产生现象,那么此时我们就会发现这是一个条件概率.那么对于此题来说,我们知道了所有的 P ( A i ) P(A_{i}) P(Ai),然后又知道了所有的 P ( B i ∣ A i ) P(Bi|Ai) P(BiAi),然后此时我们知道现象去求起因的概率,此时我们需要使用贝叶斯公式

贝叶斯公式: P ( A ∣ B ) = P ( B ∣ A ) ∗ P ( A ) / P ( B ) = P ( A ∩ B ) / P ( B ) P(A|B)=P(B|A)*P(A)/P(B)=P(A∩B)/P(B) P(AB)=P(BA)P(A)/P(B)=P(AB)/P(B)

结合到本题来说,我们的 A A A代表了每一个 A i A_{i} Ai,我们的 B B B代表的是所有k个故障现象的发生.那么对于我们的 P ( A i ∩ B ) P(Ai∩B) P(AiB)来说,就是 a i ai ai发生的同时, b 1... b j b1...bj b1...bj也发生的概率.对于我们的 P ( B ) P(B) P(B)来说,就是无所谓 a i ai ai发不发生, b 1... b j b1...bj b1...bj也发生的概率.

那么显然的我们的 P ( A i ∩ B ) = P [ A i ] ∗ P [ A i ] [ B j ] ∗ ( 1 − P [ A i ] [ B k ] ) P(Ai∩B)=P[Ai]*P[Ai][Bj]*(1-P[Ai][Bk]) P(AiB)=P[Ai]P[Ai][Bj](1P[Ai][Bk]) B j Bj Bj表示发生的现象, B k Bk Bk表示没发生这个现象
我们的 P ( B ) = ∑ 1 n P ( A i ∩ B ) P(B)=\sum_{1}^n{P(Ai∩B)} P(B)=1nP(AiB)

至此,我们的这一道题也就解决了.

#include 
using namespace std;
typedef long long ll;
#define root 1,n,1
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
	ll x=0,w=1;char ch=getchar();
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
	return x*w;
}
#define maxn 1000000
const double eps=1e-8;
#define	int_INF 0x3f3f3f3f
#define ll_INF 0x3f3f3f3f3f3f3f3f
int n,m;double p2[200][200];double p1[maxn];double p3[maxn];
int check[maxn];
struct Ans{
	int a;double b;
	bool operator < (const Ans &rhs) const {
		if(b==rhs.b) return a<rhs.a;
		else return b>rhs.b;
	}
};
int main() {
	n=read();m=read();
	for(int i=1;i<=n;i++) cin>>p1[i];
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=m;j++) {
			cin>>p2[i][j];
		}
	}
	int k=read();
	for(int i=1;i<=k;i++) {
		int num=read();check[num]=1;
	}
	double sum=0;
	for(int i=1;i<=n;i++) {
		p3[i]=p1[i];
		for(int j=1;j<=m;j++) {
			if(check[j]) {
				p3[i]=p3[i]*p2[i][j]/100;
			}
			else {
				p3[i]=p3[i]*(100-p2[i][j])/100;
			}
		}
		sum+=p3[i];
	}
	vector<Ans>ans;
	for(int i=1;i<=n;i++) {
		ans.push_back({i,p3[i]/sum});
	}
	sort(ans.begin(),ans.end());
	for(int i=0;i<ans.size();i++) {
		printf("%d %.2lf\n",ans[i].a,ans[i].b*100);
	}
	return 0;
}

你可能感兴趣的:(c++算法,#,概率论,蓝桥杯,算法,概率论)