[理综考试]
一场理综考试中有n个考生,编号为1~n,第i个考生的得分是[li,ri]中随机的一个实数
求每个考生得到每个排名的概率
Input
8
0 2
1 3
2 4
3 5
4 6
5 7
6 8
7 9
Output
0 0 0 0 0 0 0.125 0.875
0 0 0 0 0 0.125 0.75 0.125
0 0 0 0 0.125 0.75 0.125 0
0 0 0 0.125 0.75 0.125 0 0
0 0 0.125 0.75 0.125 0 0 0
0 0.125 0.75 0.125 0 0 0 0
0.125 0.75 0.125 0 0 0 0 0
0.875 0.125 0 0 0 0 0 0
绝对误差不超过10^-6算作正确
Sol:
考虑将区间离散,得到这个人分散在一些小区间以及在每个小区间的概率
枚举每一个人以及他的所属区间,得到一个概率P
因为可能会有重叠,所以设f[i][j]代表有i个人比这个人名次靠后,j个人和他在一个区间内的概率
转移见代码,注意概率计算
那么枚举i和j,这个人在[i+1,i+j+1]的排名的概率为f[i][j] * p * 1/(j+1)
累加进答案。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 100
#define eps 1e-12
using namespace std;
int n, L[maxn], R[maxn], h[maxn*2], cnt, ll, rr;
double g[maxn], f[maxn][maxn];
double getwin(int i){
if(R[i] <= rr)return 0;
if(L[i] >= rr)return 1;
return (double)(R[i]-rr)/(R[i]-L[i]);
}
double getlose(int i){
if(R[i] <= ll)return 1;
if(L[i] >= ll)return 0;
return (double)(ll-L[i])/(R[i]-L[i]);
}
void solve(int nw, int k){
ll = h[k], rr = h[k+1];
double p = (double)(rr-ll) / (R[nw]-L[nw]);
memset(f, 0, sizeof f); f[0][0] = 1;
for(int i = 1; i <= n; i ++){
if(i == nw)continue;
double win = getwin(i), lose = getlose(i), equal = 1.0-win-lose;
for(int j = i-1; j >= 0; j --){
for(int k = i-1-j; k >= 0; k --)if(f[j][k] > eps){
f[j+1][k] += lose * f[j][k];
f[j][k+1] += equal * f[j][k];
f[j][k] = win * f[j][k];
}
}
}
for(int i = 0; i < n; i ++)
for(int j = 0; j < n-i; j ++)
for(int k = 0; k <= j; k ++)
g[i+k] += f[i][j]*p/(j+1);
}
int main(){
freopen("gg.in", "r", stdin);
freopen("gg.out", "w", stdout);
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
scanf("%d%d", &L[i], &R[i]);
h[++ cnt] = L[i], h[++ cnt] = R[i];
}
sort(h+1, h+1+cnt);
cnt = unique(h+1, h+1+cnt)-h-1;
//for(int i = 1; i <= cnt; i ++)cout << h[i] << ' ';cout << endl;
for(int i = 1; i <= n; i ++){
memset(g, 0, sizeof g);
int l = lower_bound(h+1, h+1+cnt, L[i]) - h;
int r = lower_bound(h+1, h+1+cnt, R[i]) - h;
for(int j = l; j < r; j ++)solve(i, j);
for(int j = n-1; ~ j; j --)
printf("%.10lf ", g[j]); puts("");
}
return 0;
}
给时光以生命,而不是给生命以时光。

浙公网安备 33010602011771号