[jzoj 3055] 比赛 {期望dp}

版权声明:~~~感谢支持! https://blog.csdn.net/qq_39897867/article/details/88363440

题目

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多少分。答案保留到小数点后一位(注意精度)。


解题思路

将b排序,每次二分找第一个大于等于 a i a_{i} 的数,完全平方公式,相信大家都会吧,用前缀和处理一下平方和之类的即可。


代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#define rr register 
using namespace std;
int n; double a[50010],b[50010],ans,q[50010],w[50010],s; 
double qw(double x){return x*x;}
int main(){
	scanf("%d",&n); 
	for (int i=1;i<=n;i++) scanf("%lf",&a[i]); 
	for (int i=1;i<=n;i++) scanf("%lf",&b[i]); 
	sort(b+1,b+n+1); 
	for (int i=1;i<=n;i++)
	 q[i]=q[i-1]+qw(b[i]),w[i]=w[i-1]+b[i]; 
	for (int i=1;i<=n;i++) {
		int d=(lower_bound(b+1,b+n+1,a[i])-b)-1; 
		s=qw(a[i])*(2*d-n)+q[d]*2-q[n]-2*(w[d]*2-w[n])*a[i];
		ans+=s/(double)n; 
	}
	printf("%.1lf",ans); 
}

猜你喜欢

转载自blog.csdn.net/qq_39897867/article/details/88363440