• 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;
    }
    
  • 相关阅读:
    转载 NPOI.dll 用法。单元格,样式,字体,颜色,行高,宽度。读写excel
    Microsoft Visual SourceSafe 6.0 无法关联项目
    dynamic json
    c#查找string数组的某一个值的索引
    C#中 删除掉字符串数组中的空字符串
    c# 比较两个数组每一个值是否相等
    c#比较两个数组的差异
    C#动态操作DataTable(新增行、列、查询行、列等)
    C#数字转字母,ASCII码转换
    c#中使程序跳到指定行中
  • 原文地址:https://www.cnblogs.com/MakiseVon/p/10598644.html
Copyright © 2020-2023  润新知