【自主训练A:贪心博弈】B - Points Game :URAL - 1397

自主训练A:B题 - Points Game

【难度】

4.5 / 10 4.5/10 4.5/10
看了题解才会、、

【题意】

两个人,每个人每回合选择平面上的一个点。
最后每个人的选择的点集中,所有不同点对之间的距离和为每个人的分数。
若每个人都是选择最优策略,求出最后的得分差。

【数据范围】

n ≤ 500 n\le 500 n500

【样例输入】

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 , pjA,i<jdis(pi,pj)  pi , pjB,i<jdis(pi,pj)v=(pi , pjA,i<jdis(pi,pj) + pi , pjB,i<jdis(pi,pj) + piA, pjBdis(pi,pj))(pi , pjB,i<jdis(pi,pj) + pi , pjB,i<jdis(pi,pj) + piA, pjBdis(pi,pj))=(pi , pjQdis(pi,pj)  iBjQdis(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) iBjQdis(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值