【难度】
4.5
/
10
4.5/10
4.5/10
看了题解才会、、
【题意】
两个人,每个人每回合选择平面上的一个点。
最后每个人的选择的点集中,所有不同点对之间的距离和为每个人的分数。
若每个人都是选择最优策略,求出最后的得分差。
【数据范围】
n ≤ 500 n\le 500 n≤500
【样例输入】
T
2n组点对
2
0 0
0 1
1 0
1 1
2
0 0
1 0
0 3
1 5
【样例输出】
0.000
1.937
【思路】
【看了标程之后醍醐灌顶呀】
第一个人选择的点集为
A
\mathbb{A}
A
第二个人选择的点集为
B
\mathbb{B}
B
点全集为
Q
\mathbb{Q}
Q
最后的得分差为:
v
=
∑
d
i
s
(
p
i
,
p
j
)
p
i
,
p
j
∈
A
,
i
<
j
−
∑
d
i
s
(
p
i
,
p
j
)
p
i
,
p
j
∈
B
,
i
<
j
v
=
(
∑
d
i
s
(
p
i
,
p
j
)
p
i
,
p
j
∈
A
,
i
<
j
+
∑
d
i
s
(
p
i
,
p
j
)
p
i
,
p
j
∈
B
,
i
<
j
+
∑
d
i
s
(
p
i
,
p
j
)
p
i
∈
A
,
p
j
∈
B
)
−
(
∑
d
i
s
(
p
i
,
p
j
)
p
i
,
p
j
∈
B
,
i
<
j
+
∑
d
i
s
(
p
i
,
p
j
)
p
i
,
p
j
∈
B
,
i
<
j
+
∑
d
i
s
(
p
i
,
p
j
)
p
i
∈
A
,
p
j
∈
B
)
=
(
∑
d
i
s
(
p
i
,
p
j
)
p
i
,
p
j
∈
Q
−
∑
i
∈
B
∑
j
∈
Q
d
i
s
(
p
i
,
p
j
)
)
v = \underset{p_i\ ,\ p_j\in \mathbb{A},i<j}{\sum dis(p_i,p_j)} \ -\ \underset{p_i\ ,\ p_j\in \mathbb{B},i<j}{\sum dis(p_i,p_j)}\\ v = \Bigg ( \underset{p_i\ ,\ p_j\in \mathbb{A},i<j}{\sum dis(p_i,p_j)} \ +\ \underset{p_i\ ,\ p_j\in \mathbb{B},i<j}{\sum dis(p_i,p_j)}\ +\ \underset{p_i\in \mathbb{A} ,\ p_j\in \mathbb{B}}{\sum dis(p_i,p_j)} \Bigg )\\ -\Bigg ( \underset{p_i\ ,\ p_j\in \mathbb{B},i<j}{\sum dis(p_i,p_j)} \ +\ \underset{p_i\ ,\ p_j\in \mathbb{B},i<j}{\sum dis(p_i,p_j)}\ +\ \underset{p_i\in \mathbb{A} ,\ p_j\in \mathbb{B}}{\sum dis(p_i,p_j)} \Bigg )\\ =\Bigg ( \underset{p_i\ ,\ p_j\in \mathbb{Q}}{\sum dis(p_i,p_j)}\ -\ \underset{i\in \mathbb{B}}{\sum}\underset{j\in \mathbb{Q}}{\sum}dis(p_i,p_j) \Bigg )
v=pi , pj∈A,i<j∑dis(pi,pj) − pi , pj∈B,i<j∑dis(pi,pj)v=(pi , pj∈A,i<j∑dis(pi,pj) + pi , pj∈B,i<j∑dis(pi,pj) + pi∈A, pj∈B∑dis(pi,pj))−(pi , pj∈B,i<j∑dis(pi,pj) + pi , pj∈B,i<j∑dis(pi,pj) + pi∈A, pj∈B∑dis(pi,pj))=(pi , pj∈Q∑dis(pi,pj) − i∈B∑j∈Q∑dis(pi,pj))
可以看到,左项为常数,可以得到。
右项只要计算出每个点到其他所有点之间的距离即可。
那么肯定,每个人会贪心选择
∑
i
∈
B
∑
j
∈
Q
d
i
s
(
p
i
,
p
j
)
\underset{i\in \mathbb{B}}{\sum}\underset{j\in \mathbb{Q}}{\sum}dis(p_i,p_j)
i∈B∑j∈Q∑dis(pi,pj)最大的点,因为:
A选择最大的是因为不让B选,不然B的分数会更大,使得
v
v
v 变小。
B选择最大的是因为选择它会让他收益最大。
【核心代码】
时间复杂度
O
(
n
2
)
O(n^2)
O(n2)
主要是枚举点对间的距离
/*
_ __ __ _ _
| | \ \ / / | | (_)
| |__ _ _ \ V /__ _ _ __ | | ___ _
| '_ \| | | | \ // _` | '_ \| | / _ \ |
| |_) | |_| | | | (_| | | | | |___| __/ |
|_.__/ \__, | \_/\__,_|_| |_\_____/\___|_|
__/ |
|___/
*/
double aa[MAX];
double bb[MAX];
double ans[MAX];
double getdis(int a,int b){
return sqrt((bb[b] - bb[a]) * (bb[b] - bb[a]) + (aa[b] - aa[a]) * (aa[b] - aa[a]));
}
int main()
{
int n;
while(~scanf("%d",&n)){
for(int i=0;i<2*n;++i){
scanf("%lf%lf",&aa[i],&bb[i]);
}
double t = 0;
double t2 = 0;
for(int i=0;i<2*n;++i){
double dis = 0;
for(int j=0;j<2*n;++j){
dis += getdis(i,j);
if(i < j)t += getdis(i,j);
}
ans[i] = dis;
}
sort(ans,ans+2*n,greater<double>());
for(int i=0;i<2*n;++i){
if(i%2)t2 += ans[i]; /// 只有B选择的点才是需要在答案中减掉的
}
printf("%.3lf\n",t - t2);
}
return 0;
}