本文主要是介绍【牛客】寒假训练营3 J-智乃的相亲活动 题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
传送门:智乃的相亲活动
标签:概率
题目大意
智乃举办了一个相亲活动,她邀请了N位男嘉宾和M位女嘉宾,现在男女嘉宾之间存在K对双向的好感关系。活动的第一步是选出若干位心动男/女嘉宾,按照如下的方式进行。每个人都首先自己各自独立的从自己有好感的异性中选出一个人,若某个人至少被一位异性选中,则ta成为心动男!女嘉宾。现在已知这K对双向的好感关系,若每个人选择异性的方式都为从自己有好感的异性中等概率随机选择,求心动男/女嘉宾数目的期望分别是多少。
输入:第一行输入三个正整数N, M,K(1≤N,M,K ≤105)表示男女嘉宾的数目,以及双向好感关系的数目。接下来K行,每行输入两个正整数u, u(1< u< N,1<U<M)表示第u位男嘉宾和第o位女嘉宾之间存在双向好感关系。输入保证,不会出现重复的双向好感关系,且每个人至少存在一个好感关系。
输出:先输出一个字符串“float”,再输出两个实数分别代表心动男/女嘉宾数目的期望。
算法分析
- 把双向的好感关系看成无权双向边,再将嘉宾分成n个男嘉宾和m个女嘉宾,就能把这道题看作有k条边的二分图,那么自然而然就会想到匈牙利(不是)。虽然这题很像图论,但这只是一种迷惑人的表象。显然这题和概率有关,而且用到的思想是“平均”。当一个人选中n个人中每一个人的概率都相同时,我们可以直接看作他选择了每个人的n分之一,也可以理解为每个人都有n分之一的概率被选中(虽然事件之间并不独立)。
- 若某个人至少被一位异性选中,则他会成为心动嘉宾。也就是说如果这个人已经被对面某个人选中了,那么其他人再选他就没有贡献了。那么如果x对p个人有好感,y对q个人有好感,而且x和y都对z有好感,那么z就有1/p的概率被x选中,也有1/q的概率被y选中。从正面算z为心动嘉宾的概率似乎不简单,但是反面来看,他不是心动嘉宾的概率就是既没有被x选中也没有被y选中的概率,也就是(1-1/p)(1-1/q)。那他为心动嘉宾的概率就是1-(1-1/p)(1-1/q)。
- 所以只要统计一个人连接的每个对面的人连接的人数就能知道他成为心动嘉宾的概率。显然他成为心动嘉宾后对答案贡献是一,那么期望也就等于概率。再对n+m个人的期望都算出来并求和,就能得到心动男嘉宾和心动女嘉宾数目的期望了。
代码实现
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include <map>
#include <iomanip>
#include <cmath>
int a[5];
vector<int> g[2][100005];
vector<double> p[2][100005];
int main(){long long n,i,m,k,j,l,r,x,y,z,x1,y1,z1,T,c,d,h,w,mid,t;double tp,ans0=0,ans1=0;bool flag,yes;ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n>>m>>k;for(i=1;i<=k;i++){cin>>x>>y;g[0][x].emplace_back(y);g[1][y].emplace_back(x);}for(i=1;i<=n;i++)for(auto &j:g[0][i])p[1][j].emplace_back(1.0-1.0/g[0][i].size());for(i=1;i<=m;i++)for(auto &j:g[1][i])p[0][j].emplace_back(1.0-1.0/g[1][i].size());for(i=1;i<=n;i++){tp=1.0;for(auto &j:p[0][i])tp*=j;ans0+=1.0-tp;}for(i=1;i<=m;i++){tp=1.0;for(auto &j:p[1][i])tp*=j;ans1+=1.0-tp;}cout<<fixed<<setprecision(20);cout<<"float\n"<<ans0<<' '<<ans1;
}
这篇关于【牛客】寒假训练营3 J-智乃的相亲活动 题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!