LuoguP2123 皇后游戏

Description

皇后有 (n) 位大臣,每位大臣的左右手上面分别写上了一个正整数。恰逢国庆节来临,皇后决定为 (n) 位大臣颁发奖金,其中第 (i) 位大臣所获得的奖金数目为第 (i-1) 位大臣所获得奖金数目与前 (i) 位大臣左手上的数的和的较大值再加上第 (i) 位大臣右手上的数。

形式化地讲:我们设第 (i) 位大臣左手上的正整数为 (a_i),右手上的正整数为 (b_i),则第 (i) 位大臣获得的奖金数目为 (c_i) 可以表达为:

$$c_i=egin{cases}
a_1+b_1 & i=1
max(c_{i-1},sum_{j=1}^i a_j)+b_i & 2leq ileq n
end{cases}$$

当然,吝啬的皇后并不希望太多的奖金被发给大臣,所以她想请你来重新安排一下队伍的顺序,使得获得奖金最多的大臣,所获奖金数目尽可能的少。

注意:重新安排队伍并不意味着一定要打乱顺序,我们允许不改变任何一位大臣的位置。

Input

第一行包含一个正整数 (T) ((1leq Tleq10)),表示测试数据的组数。

接下来 (T) 个部分,每个部分的第一行包含一个正整数 (n) ((1leq nleq20000)),表示大臣的数目。

每个部分接下来 (n) 行中,每行两个正整数,分别为 (a_i)(b_i) ((1leq a_i,b_ileq10^9)),含义如上文所述。

Output

(T) 行,每行包含一个整数,表示获得奖金最多的大臣所获得的奖金数目。

Example

Input Output
1
3
4 1
2 2
1 2
8
Input Output
2
5
85 100
95 99
76 87
60 97
79 85
12

Solution

LuoguP1080 国王游戏 类似,采用贪心的策略。

考虑:若第 (k) 个大臣与第 (k+1) 个大臣交换位置后,两者间获得的较多奖金的一方的奖金减少。

设:排在第 (k) 个大臣前面的所有人的左手上的数的和为 (s) ((k=1,s=0)),第 (k-1) 大臣的奖金为 (c) ((k=1,c=0))(a_i)(b_i) 依题设 ,

则有 (max(max(c,s+a_{k+1})+b_{k+1},s+a_k+a_{k+1})+b_k<max(max(c,s+a_k)+b_k,s+a_k+a_{k+1})+b_{k+1})

我们先证明 ((1)) (max(x,z)<max(y,z)) 作为交换 (x)(y) 的条件时与 ((2)) (x<y) 等价:

(xgeq y),则不满足 ((1))((2)),不交换 (x)(y)
(x<y),则满足 ((2)),交换 (x)(y),不满足 ((1))((2))

综上,探究这类问题时,形如 (max(x,z)<max(y,z)) 的式子可化为 (x<y)

回到原题,

原式即 (max(c-s,a_{k+1},a_k+a_{k+1}-b_{k+1})+s+b_k+b_{k+1}<max(c-s,a_k,a_k+a_{k+1}-b_k)+s+b_k+b_{k+1})

(max(a_{k+1},a_k+a_{k+1}-b_{k+1})<max(a_k,a_k+a_{k+1}-b_k))

(max(-a_k,-b_{k+1})<max(-a_{k+1},-b_k))

((*)) (min(a_k,b_{k+1})>min(a_{k+1},b_k))

很遗憾,这并不是一个偏序关系,因为其不具有传递性。
举个栗子:((3,5))((1,1))((1,7)) 这个序列相邻的序偶均满足 ((*)),而 ((1,1))((1,7))((3,5)) 这样排序也满足 ((*)),前者答案为 (16) ,后者答案为 (14) ,显然后者更优,我们如果单纯按照 ((*)) 排序,无法保证结果的正确性。

实际上,我们可以在此之上进行一定的改良:

考虑 ((*)) 不具有传递性的原因,当 (min(a_k,b_{k+1})=min(a_{k+1},b_k)) 时,不管我们交不交换,该条件均成立,这种不确定性会造成结果的不一致,这一点正是 ((*)) 不具有传递性的原因。如在上面举出的栗子中,((3,5))((1,1)) 交换与否就影响了最后的结果,可以看出 (a_i)(b_i) 的相对关系也会对最终的序列的顺序产生影响,我们不妨从如何消除这种影响开始考虑,既然 (a_i)(b_i) 的相对关系会影响排序,那么我们可以按相对关系将序偶分组,组内排好序后再按组排序。

设:(d_i=sgn(a_i-b_i))

首先,我们按 (d_i) 将序偶分成三组,
在同一组内,序偶之间不存在 (a_i)(b_i) 的相对关系不一致的情况,易知在这种情况下 ((*)) 具有传递性。具体来说就是:

对于 (d_i=-1) 的一组,若满足 ((*)),则 (a_k>a_{k+1}),即按 (a_i) 升序排序即可
对于 (d_i=0) 的一组,则始终不满足 ((*)),则无须排序
对于 (d_i=1) 的一组,若满足 ((*)),则 (b_{k+1}>b_k),即按 (b_i) 降序排序即可

接下来考虑按组排序,

显然 (d_i=0) 的一组可以和其他的一组任意排序,那么我们将这一组放在中间即可
(d_k=1)(d_{k+1}=-1),则必满足 ((*)),则 (d_i=-1) 的一组应放在 (d_k=1) 的一组的前面

如此,我们便得到了最终的序列,再遍历所有大臣求最大的奖金即可。


Code

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef struct{
    int a,b,d;
}h_type;

const int n_size=20005;

int T,n;
ll c[n_size];
h_type h[n_size];

bool cmp(h_type &x,h_type &y);

int main(void){
    scanf("%d",&T);
    for(int i=1;i<=T;i++){
        scanf("%d",&n);
        for(int j=1;j<=n;j++){
            scanf("%d%d",&h[j].a,&h[j].b);
            if(h[j].a==h[j].b)  h[j].d=0;
            else if(h[j].a<h[j].b)  h[j].d=-1;
            else    h[j].d=1;
        }
        sort(h+1,h+n+1,cmp);
        ll sum=0;
        for(int j=1;j<=n;j++){
            sum+=h[j].a;
            c[j]=max(c[j-1],sum)+h[j].b;
        }
        printf("%lld
",c[n]);
    }
    return 0;
}

bool cmp(h_type &x,h_type &y){
    if(x.d!=y.d)    return x.d<y.d;
    if(x.d==-1) return x.a<y.a;
    if(x.d==1)  return x.b>y.b;
    return false;
}
原文地址:https://www.cnblogs.com/MakiseVon/p/10598644.html