Jzoj 3055NOIP2012模拟10.27期望比赛
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jzoj 3055NOIP2012模拟10.27期望比赛相关的知识,希望对你有一定的参考价值。
Link
题面
Description
有两个队伍A和B,每个队伍都有n个人。这两支队伍之间进行n场1对1比赛,每一场都是由A中的一个选手与B中的一个选手对抗。同一个人不会参加多场比赛,每个人的对手都是随机而等概率的。例如A队有A1和A2两个人,B队有B1和B2两个人,那么(A1 vs B1,A2 vs B2)和(A1 vs B2,A2 vs B1)的概率都是均等的50%。
每个选手都有一个非负的实力值。如果实力值为X和Y的选手对抗,那么实力值较强的选手所在的队伍将会获得(X-Y)^2的得分。
求A的得分减B的得分的期望值。
Input
第一行一个数n表示两队的人数为n。
第二行n个数,第i个数A[i]表示队伍A的第i个人的实力值。
第三行n个数,第i个数B[i]表示队伍B的第i个人的实力值。
Output
输出仅包含一个实数表示A期望赢B多少分。答案保留到小数点后一位(注意精度)。
Sample Input
2
3 7
1 5
Sample Output
20.0
Data Constraint
对于30%的数据,n≤50。
对于100%的.据,n≤50000;A[i],B[i]≤50000。
解题思路
考场上已经打到正解了,结果概率处理写错了[怒][怒][怒]
以下先不说概率,最后再说
完全平方式都会拆吧,拆完之后 ∑ a 2 + b 2 − 2 a ⋅ b \\sum a^2+b^2-2a·b ∑a2+b2−2a⋅b,当然还有b比a大 ∑ − ( a 2 + b 2 + 2 a ⋅ b ) \\sum -(a^2+b^2+2a·b) ∑−(a2+b2+2a⋅b) = ∑ − a 2 − b 2 + 2 a ⋅ b \\sum -a^2-b^2+2a·b ∑−a2−b2+2a⋅b
先算平方和,再算那什么2a·b
把a和b都丢到一个数组里排序,然后O(n)处理前面和后面
如果当前是a,前面有x个b比它小(产生分数为正),后面有y个b比它大(产生分数为负)
那么a的平方和为
a
2
∗
x
−
a
2
∗
y
=
a
2
∗
(
x
−
y
)
a ^ 2 * x - a ^ 2 * y= a ^ 2 * (x - y)
a2∗x−a2∗y=a2∗(x−y)
b也一样
用两个变量累计前面的b的和,后面的b的和
那个2*balabala,
2
∗
a
∗
q
i
a
n
−
2
∗
a
∗
h
o
u
=
2
∗
a
(
q
i
a
n
−
h
o
u
)
2 * a * qian - 2 * a * hou = 2 * a(qian - hou)
2∗a∗qian−2∗a∗hou=2∗a(qian−hou)
然后全部加起来就好了
再说概率
每个分数乘上这两个数互打概率,
n
!
n
=
(
n
−
1
)
!
\\frac{n!}{n}=(n - 1)!
nn!=(n−1)!
然后最后每种组合都要除以出现概率(多少种组合),
a
n
s
n
!
\\frac{ans}{n!}
n!ans
那
(
n
−
1
)
!
n
!
\\frac{(n-1)!}{n!}
n!(n−1)!不就是
1
n
\\frac{1}{n}
n1了吗
只用在输出的时候用ans / n就好了
Code
#include <algorithm>
#include <iostream>
#include <cstdio>
#define ll unsigned long long
#define ldb long double
#define N 501000
using namespace std;
struct DT{
ldb s;
int i, id;
ldb q, h;
}c[2 * N];
ldb ans, chu;
int n;
ldb x, jian, jia, qian[N], hou[N];
bool cmp(const DT&k, const DT&l) {
if(k.s == l.s) return k.i < l.i;
return k.s < l.s;
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++) {
scanf("%Lf", &x);
c[i] = (DT){x, i, 1, (ldb)1, (ldb)-1};
//q,h标记产生分数的正负;a和b是不一样的
}
for(int i = 1; i <= n; i ++) {
scanf("%Lf", &x);
jia += x;
c[i + n] = (DT){x, i, 2, (ldb)-1, (ldb)1};
}
sort(c + 1, c + 1 + n * 2, cmp);
for(int i = 1; i <= n * 2; i ++) {
if(c[i].id != c[i - 1].id) //一个a一个b,假设当前是a,上一个是b
qian[i] = (i - 1) - qian[i - 1];
//(i-1)是前面有多少个数,qian[i-1]就是前面有多少个a,减掉之后就是有多少个前面b
else qian[i] = qian[i - 1];
}
for(int i = n * 2; i; i --) {
if(c[i].id != c[i + 1].id) //同上
hou[i] = (n * 2 - i) - hou[i + 1];
else hou[i] = hou[i + 1];
}
for(int i = 1; i <= n * 2; i ++) {
if(c[i].id == 2)
jian += c[i].s, jia -= c[i].s; //更新前面、后面b的和
else ans += (ldb)(2 * (ldb)c[i].s * (ldb)(jia - jian)); //加上2*a*b
ans += (ldb)(c[i].s * c[i].s * (c[i].q * qian[i] + c[i].h * hou[i])); //加上a^2或b^2
}
printf("%.1Lf", ans / n); //除以n
}
以上是关于Jzoj 3055NOIP2012模拟10.27期望比赛的主要内容,如果未能解决你的问题,请参考以下文章
Jzoj 3056NOIP2012模拟10.27容斥DP数学数字
10.27 noip模拟试题(afternoon)(跪在游戏玩少了2333)