• 皇后问题(题解)


    皇后游戏
    【引子】
    还记得NOIP 2012 提高组Day1 的国王游戏吗?时光飞逝,光阴荏苒,两年
    过去了。早已过时的国王游戏如今已被皇后游戏取代,请你来解决类似于国王游
    戏的另一个问题。
    【问题描述】
    皇后有n 位大臣,每位大臣的左右手上面分别写上了一个正整数。恰逢劳动
    节来临,皇后决定为n 位大臣颁发奖金,其中第i 位大臣所获得的奖金数目为第
    i-1 位大臣所获得奖金数目与前i 位大臣左手上的数的和的较大值再加上第i 位
    大臣右手上的数。
    当然,吝啬的皇后并不希望太多的奖金被发给大臣,所以她想请你来重新安
    排一下队伍的顺序,使得获得奖金最多的大臣,所获奖金数目尽可能的少。
    注意:重新安排队伍并不意味着一定要打乱顺序,我们允许不改变任何一
    位大臣的位置。
    【输入格式】
    第一行包含一个正整数T,表示测试数据的组数。
    接下来T 个部分,每个部分的第一行包含一个正整数n,表示大臣的数目。
    每个部分接下来n 行中,每行两个正整数,分别为ai 和bi,含义如上文所述。
    【输出格式】
    共T 行,每行包含一个整数,表示获得奖金最多的大臣所获得的奖金数目。
    【样例输入1】
    1
    3
    4 1
    2 2
    1 2
    NOI 2016 模拟训练 皇后游戏
    第 3 页 共 8 页
    【样例输出1】
    8
    【样例说明1】
    按照 1、2、3这样排列队伍,获得最多奖金的大臣数目为 10;
    按照 1、3、2这样排列队伍,获得 最多奖金的大臣获得数目为 9;
    按照 2、1、3这样排列队伍,获得最多奖金的大臣数目为 9;
    按照 2、3、1这样排列队伍,获得最多奖金的大臣数目为 8;
    按照 3、1、2这样排列队伍,获得最多奖金的大臣数目为 9;
    按照 3、2、1这样排列队伍,获得最多奖金的大臣数目为 8。
    当按照 3、2、1这样排列队伍时,三位大臣左右手的数分别为:
    (1, 2)、(2, 2)、(4, 1)
    第 1位大臣获得的奖金为 1 + 2 = 3;
    第 2位大臣获得的奖金为 max{3, 3} + 2 = 5;
    第 3为 大臣获得的奖金max{5, 7} + 1 = 8。
    【样例输入2】
    2
    5
    11 89
    28 32
    4 78
    31 93
    39 33
    12
    9 75
    52 28
    1 73
    100 46
    4
    55 53
    94 89
    53 44
    3 2
    39 35
    26 51
    5 29
    【样例输出2】
    360
    535
    对于全部测试数据满足 :1 ≤ ai, bi ≤ 109。

     

    这道题,呵呵,看似简单,实则也有点简单。

    这是题解,我猜是个人都看不懂,甚至连什么高考题都出来了。

    但是感觉本人的思路还是很好的:

    先对bi进行排序,因为它算的最终值中肯定有bi[i],也就是当前的bi的值,所以可以把所有数组都初始化成每个bi的值。

    当然,式子中还有第i-1 位大臣所获得奖金数目与前i 位大臣左手上的数的和的较大值,所以由此可以推断出这个终值中一定有上一个的ai的值,所以最后只要比较当前的ai的值和上一个bi的值哪个大就行。

    代码:

    //#include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cstdlib>
    #include <vector>
    #include <set>
    #include <algorithm>
    #define mp make_pair
    #define fi first
    #define se second
     
    using namespace std;
    
    typedef long long int64;
    typedef pair<int,int> PII;
    const int MAXN=200005;
     
    int n;
    PII a[MAXN];
    int64 dp[MAXN];
    
    inline bool cmp(const PII &x,const PII &y)
    {
        return min(x.fi,y.se)<min(x.se,y.fi);
    }
     
    int main()
    {
        //freopen ("game.in","r",stdin);
        //freopen ("game.out","w",stdout);
        int testCase;
        for (scanf("%d",&testCase);testCase;testCase--)
        {
            scanf("%d",&n);
            for (int i=1;i<=n;i++) scanf("%d%d",&a[i].fi,&a[i].se);
            sort(a+1,a+n+1,cmp);
            int64 s=0;
            for (int i=1;i<=n;i++)
            {
                s+=a[i].fi;
                dp[i]=max(s,dp[i-1])+a[i].se;
            }
            cout<<dp[n]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    跳出iframe
    leetcode 225. Implement Stack using Queues
    leetcode 206. Reverse Linked List
    leetcode 205. Isomorphic Strings
    leetcode 203. Remove Linked List Elements
    leetcode 198. House Robber
    leetcode 190. Reverse Bits
    leetcode leetcode 783. Minimum Distance Between BST Nodes
    leetcode 202. Happy Number
    leetcode 389. Find the Difference
  • 原文地址:https://www.cnblogs.com/Zhoier-Zxy/p/8595795.html
Copyright © 2020-2023  润新知