• 邻项交换排序


    邻项交换排序

    通过找到 决定 相邻两个单位位置 的策略 以推广到整个队伍,是一种通过贪心解决问题的方法。

    题目大意

    有n个大臣,第i位大臣左手的数为ai,右手的数为bi,且aibi均为正整数。他能获得的数ci由以下关系给出: 

    ci最大的大臣的ci最小为多少。

    分析

    Part 1

    我们要找大臣的顺序,且排列顺序没有后效性,我们不妨拎出相邻的大臣i与大臣j。

    设这两位大臣之前的大臣获得的奖金为y,之前的所有大臣左手上的数之和为x。

    ①当大臣1排在大臣2之前时:

    大臣i的奖金:max( y,x+ai )+bi

    大臣j的奖金:max( ci,x+ai+a)+bj

    ②当大臣1排在大臣2之前时:

    大臣j的奖金:max( y,x+aj )+bj

    大臣i的奖金:max( cj,x+ai+a)+bi

    我们比较两种情况,分析满足何种条件时我们才能把大臣i放在前面。

    显然,当一个大臣被放在后面时,一定比他放在前面时得到的奖金多(证明略)

    为了比较奖金最多大臣的奖金多少,我们进而比较被放在后面时两个大臣的奖金数。

    为使情况最优,max( ci,x+ai+a)+b< max( cj,x+ai+a)+bi

    => max( max( y,x+ai )+bi,x+ai+a)+b< max( max( y,x+aj )+bj,x+ai+a)+bi

    => max( y+bi,x+ai+bi,x+ai+a)+b< max( y+bj,x+aj+bj,x+ai+a)+bi

    => max( y+bi+bj,x+ai+bi+bj,x+ai+a+bj) < max( y+bj+bi,x+aj+bj+bi,x+ai+aj+bi )

     由于两式中都有 y+bi+bj,我们忽略不计算。

    =>  max( x+ai+bi+bj,x+ai+a+bj) < max( x+aj+bj+bi,x+ai+aj+bi )

    为化简式子,我们同时减去 x+ai+aj+bi+bj

    => max( -aj,-bi) < max( -ai,-bj )

    => min( aj,b) < min( ai,bj )

    Part 2

    于是如果您的sort的cmp函数写成:

    bool operator <(node a) const
    {
         return min(x,a.y)<min(y,a.x);
    }

    或许能水过洛谷的数据,但是是错解。

    这里从Luogu题解中找到了一组hack数据:

    2

    7

    6 3

    1 1

    7 3

    1 1

    1 6

    1

    6 10

    7

    10

    1

    3

    1

    3

    1

    1 6

    上面两组数据只是顺序不一样,结果应该是一样的,但用上面的程序跑出来的结果却是不一样的。

    再具体地分析一下。假设有三位大臣,他们的a[i]和b[i]分别是:

    7 3

    1 1

    1 6

    显然,这样可以是排完序后的结果,因为两两之间用条件判断都是等于。这样算出来答案是17。而如果这样排:

    1 1

    1 6

    7 3

    答案是12,显然这样更优,但程序却有可能排成17的那种情况。

    为什么错了呢?简单来说,就是此时的判断条件不满足传递性。引用一个名词——严格弱序。sort的判断函数必须满足严格弱序。

    严格弱序是什么?

    拿内置类型来说,C++都定义了 “<”操作符,这就是一个严格弱序,而“<=”就不是一个严格弱序

    对于内置类型我们自然可以有<、>、=来判断两个值的大小关系,而对于自定义的类型,只用一个严格弱序(这里就用<为例)就可以表示两个元素三种大小关系

    a小于b

    a < b

    b小于a

    b < a

    a等于b

    !(a < b) && !( b < a )

    严格弱序的三点要求:

    1.两个关键字不能同时“严格弱序”于对方

    2.如果a“严格弱序”于b,且b“严格弱序”于c,则a必须“严格弱序”于c(传递性)

    3.如果存在两个关键字,任何一个都不“严格弱序”于另一个,则这两个关键字是相等的。

    摘自WikiPedia的定义:

    strict weak ordering is a binary relation < on a set S that is a strict partial order (a transitive relation that is irreflexive, or equivalently,[5] that is asymmetric) in which the relation "neither a < b nor b < a" is transitive.[1] Therefore, a strict weak ordering has the following properties:

    • For all x in S, it is not the case that x < x (irreflexivity).
    • For all xy in S, if x < y then it is not the case that y < x (asymmetry).
    • For all xyz in S, if x < y and y < z then x < z (transitivity).
    • For all xyz in S, if x is incomparable with y (neither x < y nor y < x hold), and y is incomparable with z, then x is incomparable with z (transitivity of incomparability).

    This list of properties is somewhat redundant, as asymmetry follows readily from irreflexivity and transitivity.

    非严格弱序带来的问题:

    有序关联容器不允许存在相同的关键字,在判断时,会认为相同的关键字是不相等的,因此会将两个相同的关键字插入容器中,这个行为是未定义的。

    注:以上部分严格弱序的叙述摘自 C++ 严格弱序  River_Lethe

    Part 3

    那么,如果必须使用严格弱序,应该如何判断 min( aj,b) < min( ai,bj ) 呢?

    我们分情况讨论:

    1.当ai biaj​ bj时,ai​ ≤ aj,应该按a升序排序(aiaj相等时无所谓)。

    2.当ai​ biaj​ bj时,爱怎么排怎么排。

    3.当ai​ biaj​ bj时,bi ≥ bj,应该按b降序排序。

    //判断a[i].x 与 b[i].x 的大小关系
    if (a[i].x>a[i].y) a[i].d=1;
    else if (a[i].x<a[i].y) a[i].d=-1;
    else a[i].d=0;

    于是cmp将是这样的:

    bool operator <(node a) const
    {
        if (d!=a.d) return d<a.d;
        if (d<=0) return x<a.x;
        return y>a.y;
    }
  • 相关阅读:
    【二分图匹配入门专题1】L
    【二分图匹配入门专题1】K
    【km算法模板+总结】
    【二分匹配入门专题1】J
    【自定义博客园~~~】
    【二分图匹配入门专题1】I
    【二分图匹配入门专题1】H
    【二分图匹配入门专题1】G
    【二分图匹配入门专题1】E
    【二分图匹配入门专题1】F
  • 原文地址:https://www.cnblogs.com/Cindy-Chan/p/11224939.html
Copyright © 2020-2023  润新知