• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
scorpiorax
博客园    首页    新随笔    联系   管理    订阅  订阅
皇后游戏

皇后游戏
【引子】
还记得 NOIP 2012 提高组 Day1 的国王游戏吗?时光飞逝,光阴荏苒,两年
过去了。早已过时的国王游戏如今已被皇后游戏取代,请你来解决类似于国王游
戏的另一个问题。
【问题描述】
皇后有 n 位大臣,每位大臣的左右手上面分别写上了一个 正 整数。恰逢劳动
节来临,皇后决定为 n 位大臣颁发奖金,其中第 i 位大臣所获得的奖金数目为第
i-1 位大臣所获得奖金数目与前 i 位大臣左手上的数的和的较大值再加上第 i 位
大臣右手上的数。
形式化地讲:我们设第 i 位大臣左手上的正整数为 a i ,右手上的正整数为 b i ,
则第 i 位大臣获得的奖金数目为 c i 可以表达为:


当然,吝啬的皇后并不希望太多的奖金被发给大臣,所以她想请你来重新安
排一下队伍的顺序,使得获得奖金最多的大臣,所获奖金数目尽可能的少。
注意:重新安排队伍并不意味着一定要打乱顺 序,我们允许不改变任何一
位大臣的位置。
【输入格式】
第一行包含一个正整数 T,表示测试数据的组数。
接下来 T 个部分,每个部分的第一行包含一个正整数 n,表示大臣的数目。
每个部分接下来 n 行中,每行两个正整数,分别为 a i 和 b i ,含义如上文所述。
【输出格式】
共 T 行,每行包含一个整数,表示获得奖金最多的大臣所获得的奖金数目。
【样例输入 1】
1
3
4 1
2 2
1 2

【样例输出 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 4
55 53
94 89
53 44
3 2
39 35
26 51
5 29
【样例输出 2】
360
535

 1 //#include <cmath>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <string>
 6 #include <cstdlib>
 7 #include <vector>
 8 #include <set>
 9 #include <algorithm>
10 #define mp make_pair
11 #define fi first
12 #define se second
13  
14 using namespace std;
15 
16 typedef long long int64;
17 typedef pair<int,int> PII;
18 const int MAXN=200005;
19  
20 int n;
21 PII a[MAXN];
22 int64 dp[MAXN];
23 
24 inline bool cmp(const PII &x,const PII &y)
25 {
26     return min(x.fi,y.se)<min(x.se,y.fi);
27 }
28  
29 int main()
30 {
31     //freopen ("game.in","r",stdin);
32     //freopen ("game.out","w",stdout);
33     int testCase;
34     for (scanf("%d",&testCase);testCase;testCase--)
35     {
36         scanf("%d",&n);
37         for (int i=1;i<=n;i++) scanf("%d%d",&a[i].fi,&a[i].se);
38         sort(a+1,a+n+1,cmp);
39         int64 s=0;
40         for (int i=1;i<=n;i++)
41         {
42             s+=a[i].fi;
43             dp[i]=max(s,dp[i-1])+a[i].se;
44         }
45         cout<<dp[n]<<endl;
46     }
47     return 0;
48 }

 

 

***考试的时候想的很天真哇,按左手从小到大拍个序站成一排计算值,然后再按右手从小到大排个序站成一排计算值取最小值,后来发现样例过不去哇,肿么办好叻,随手一删留下左手站队法吼吼吼好歹过了一个样例。。。。虽说最后也就五分。。。

***看了n久的题解。。好像明白了一丢丢他的意思哇,大概就是如果你站我前面你所得的值是多少,如果我站你前面比你值小,那我就站你前面好喽。。but我也不大清楚我理解是否有误叭。。。。。。

 

posted on 2018-03-20 00:44  scorpiorax  阅读(192)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3