zoukankan      html  css  js  c++  java
  • 皇后问题(题解)

    皇后游戏
    【引子】
    还记得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;
    }
  • 相关阅读:
    最流行的javascript 代码规范
    jquery里阻止冒泡ev.stopPropagation()
    jquery里阻止冒泡ev.stopPropagation()
    响应式页面设计原理
    fromCharCode()的用法
    slice的用法
    java 反转数组
    java 一个数组的长度
    Java访问数组
    java 数组的定义
  • 原文地址:https://www.cnblogs.com/Zhoier-Zxy/p/8595795.html
Copyright © 2011-2022 走看看