题目:有n 把钥匙,m 个锁,每把锁只能由一把特定的钥匙打开,其他钥匙都无法打开。一把钥匙可能可以打开多把锁,钥匙也可以重复使用。 对于任意一把锁来说,打开它的钥匙是哪一把是等概率的。但你无法事先知道是哪一把钥匙,只能进行尝试。 已知每次尝试用第i把钥匙打开第j把锁会消耗的时间a ij 秒。 问最优策略下打开所有锁的总期望时间是多少秒。
输入描述 第一行两个以空格分隔的正整数n,m。 接下来n行每行m个空格分隔的正整数aij。 1<=n,m,aij <=500
输出描述 输出一个小数代表答案,你的答案会被认为是正确的当且仅当你的答案与正确答案的绝对误差或相对误差不超过10-6。
1/3的概率选对了a0(a0*1/3),2/3的概率没选对,但也花了a0的时间,那就要2/3*a0,接下来就是1/2选对了a1(a1*1/2),1/2没选对,但也花了a1的时间,那就要加上1/2*a1,最后必然选对了a3
(根据题意模拟就能找对解决方案)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> a(m, vector<int>(n));
for (int j = 0; j < n; ++j) {
for (int i = 0; i < m; ++i) {
cin >> a[i][j];
}
}
double ans = 0;
for (int i = 0; i < m; ++i) {
sort(a[i].begin(), a[i].end());
for (int j = 0; j < n; ++j) {
ans += (n - j) * a[i][j];
}
}
printf("%.6lf\n", ans / n);
return 0;
}
这与一个古典概型计算概率:钥匙乱序问题很类似,但也不完全像,这里记录一下钥匙乱序问题的思路,原问题:有外形相同的n把锁和n把钥匙,每把钥匙只能打开其中的一把锁,现将锁和钥匙随机配对,每对锁和钥匙各一把,试求至少有一把锁能被所配对钥匙打开的概率。
至少有一把锁能配对 = 有一把锁能配对 + 有两把锁能配对 +… + 有n把锁能配对
本题如果按照古典概率去求,比较难计算,因为很多情况交集在一起,不如按照概率公式去求,
例如三个事件的情况:P(AUBUC)=P(A)+P(B)+P(C)-P(AB)-P(AC)-P(BC)+P(ABC)
对于P(A)或者P(B)或者P(C)的计算,即有一把钥匙能够配对成功的概率,不仅仅只是第 i 把锁独立配对成功的事件,它同时也包含了其他锁配对成功的事件,即它代表的是凡是包含有第 i 把锁配对成功的所有事件。
举个例子,假设 有 4把锁,4把钥匙,计算第一把钥匙配对成功的概率。
下面列出所有的事件组合
锁1 — 钥1 钥1 钥1 钥1 钥1 钥1 钥2 钥2 钥2 钥2 钥2 钥2
锁2 — 钥2 钥2 钥3 钥3 钥4 钥4 钥1 钥1 钥3 钥3 钥4 钥4
锁3 — 钥3 钥4 钥2 钥4 钥2 钥3 钥3 钥4 钥2 钥4 钥2 钥3
锁4 — 钥4 钥3 钥4 钥2 钥3 钥2 钥4 钥3 钥4 钥2 钥3 钥2
锁1 — 钥3 钥3 钥3 钥3 钥3 钥3 钥4 钥4 钥4 钥4 钥4 钥4
锁2 — 钥1 钥1 钥2 钥2 钥4 钥4 钥1 钥1 钥2 钥2 钥3 钥3
锁3 — 钥3 钥4 钥1 钥4 钥1 钥2 钥2 钥3 钥1 钥3 钥1 钥2
锁4 — 钥4 钥3 钥4 钥1 钥2 钥1 钥3 钥2 钥3 钥1 钥2 钥1
由上图可以看出,4把钥匙的所有事件就是4的全排列=4!= 24。
那么第一把锁能成功配对的事件只有钥匙1排在最前面的前面那6个事件,在这6个事件中,除了钥匙1以外的其他钥匙(n-1)构成一个全排列,就是3!=6。
所以:
同理,有两把同时配对成功的总事件数还是 n!,有效事件数是 (n-2)!(除了配对成功的两把钥匙外构成的全排列)
概率计算是:P(AiAj)=(n-2)!/n!
所以:
这就是著名的“乱序问题” ,得到概率公式后,要用极限定理去求他的概率: