贪心算法——皇后游戏(洛谷P2123)
贪心算法——皇后游戏
- 1、题目描述
- 2、问题分析
- 3、算法源码
1、题目描述
题目背景
还记得 NOIP 2012 提高组 Day1 的国王游戏吗?时光飞逝,光阴荏苒,两年过去了。国王游戏早已过时,如今已被皇后游戏取代,请你来解决类似于国王游戏的另一个问题。
题目描述
皇后有 n 位大臣,每位大臣的左右手上面分别写上了一个正整数。恰逢国庆节来临,皇后决定为 n 位大臣颁发奖金,其中第 i 位大臣所获得的奖金数目为第i-1 位大臣所获得奖金数目与前 i 位大臣左手上的数的和的较大值再加上第 i 位大臣右手上的数。
形式化地讲:我们设第 i 位大臣左手上的正整数为 ai,右手上的正整数为 bi,则第 i 位大臣获得的奖金数目为 ci可以表达为:
当然,吝啬的皇后并不希望太多的奖金被发给大臣,所以她想请你来重新安排一下队伍的顺序,使得获得奖金最多的大臣,所获奖金数目尽可能的少。
注意:重新安排队伍并不意味着一定要打乱顺序,我们允许不改变任何一位大臣的位置。
输入格式
第一行包含一个正整数 T,表示测试数据的组数。
接下来 T 个部分,每个部分的第一行包含一个正整数 n,表示大臣的数目。
每个部分接下来 n 行中,每行两个正整数,分别为 ai和 bi,含义如上文所述。
输出格式
共 T 行,每行包含一个整数,表示获得奖金最多的大臣所获得的奖金数目。
输入输出样例
输入 #1 复制
1
3
4 1
2 2
1 2
输出 #1 复制
8
输入 #2 复制
2
5
85 100
95 99
76 87
60 97
79 85
12
9 68
18 45
52 61
39 83
63 67
45 99
52 54
82 100
23 54
99 94
63 100
52 68
输出 #2 复制
528
902
说明/提示
按照 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。
对于全部测试数据满足:T <= 10, 1 <= n <= 20000,1 < ai,bi < 10^9
2、问题分析
这题乍一看和P1080 国王的游戏很像啊,因此咱还是根据题意先用数学的思想建模推导一番:
设第i个大臣的收益为ci,左手金额为ai,右手金额为bi,第j个大臣的收益为cj,左手金额为aj,右手金额为bj,第i个大臣前i-1个人的金额之和为x,第i-1个大臣的收益为y。
左手金额 右手金额 前i-1个人 x /第i个大臣 ai bi第j个大臣 aj bj
根据题目的要求,有:
ci = max{y,x+ai} + bi
cj = max{ci,x+ai+aj}+bj
= max{max{y,x+ai} + bi,x+ai+aj}+bj
= max{y+bi+bj,x+ai+bi+bj,x+ai+aj+bj}
此时两位大臣的中的较大收益记为C1, 显然
C1 = cj = max{y+bi+bj,x+ai+bi+bj,x+ai+aj+bj}
因为我们是要研究排列的方式对整体最大收益的影响,因而改变第i个大臣和第j个大臣的排列
左手金额 右手金额 前i-1个人 x /第j个大臣 aj bj第i个大臣 ai bi
根据题目的要求,有:
cj = max{y,x+aj} + bj
ci = max{cj,x+ai+aj}+bi
= max{max{y,x+aj} + bj,x+ai+aj}+bi
= max{y+bi+bj,x+aj+bi+bj,x+ai+aj+bi}
此时两位大臣的中的较大收益记为C2, 显然
C2 = ci = max{y+bi+bj,x+aj+bi+bj,x+ai+aj+bi}
设C1为C1、C2中的较小者,则 C1 <= C2
max{y+bi+bj,x+ai+bi+bj,x+ai+aj+bj}
<= max{y+bi+bj,x+aj+bi+bj,x+ai+aj+bi}
=>
max{x+ai+bi+bj,x+ai+aj+bj}
<=max{x+aj+bi+bj,x+ai+aj+bi}
=>
max{ai+bi+bj,ai+aj+bj}<=max{aj+bi+bj,ai+aj+bi}
=>
max{bi,aj}+ai+bj<=max{bj,ai}+aj+bi
=>
max{bi,aj}-aj-bi <= max{bj,ai}-ai-bj
=>
-min{aj,bi}<=-min{ai,bj}
=>
min{ai,bj}<=min{aj,bi}
同理,设C2为C1、C2中的较小,可得到类似推论。
但这题与P1080国王的游戏不同的是,ai,bi,aj,bj之间没有明显的直接大小关系,而直接用式子min{ai,bj}<=min{aj,bi}进行排序,会容易出问题,所以我们需要分情况讨论ai,bi,aj,bj之间的大小关系。
考虑到直接进行分类判断情况过于冗杂,故引入变量d = a - b/|a-b|,表示每个大臣左右手金额大小关系,d的值有三种情况,
①、d = 1, 即a > b,
②、d = 0, 即a = b,
③、d = -1, 即a < b
此时情况可分为以下三种:
(1)、di < dj
(2)、di > dj
(3)、di = dj
对于情况(1):因为di<dj,所以ai-bi<aj-bj,设此时ai<aj,bi>bj(因为令ai<aj,bi>bj可使得ai-bi<aj-bj),为满足式子min{ai,bj}<=min{aj,bi},令ai<bi,bj<aj,即di=ai-bi<0,dj=aj-bj>0,满足di<dj,按di<dj排序即可。
对于情况(2):因为di>dj,所以ai-bi>aj-bj,设此时ai>aj,bi<bj,为满足式子min{ai,bj}<=min{aj,bi},令ai<bi,bj<aj,即di=ai-bi<0,dj=aj-bj>0,满足di<dj,按di<dj排序即可。
对于情况(3):因为di=dj,
①设di < 0,dj < 0,即ai < bi, aj < bj,为满足式子min{ai,bj}<=min{aj,bi},则ai<aj,按ai<aj排序即可。
②、设di = 0,dj = 0,即ai=bi,aj=bj,此时式子min{ai,bj}<=min{aj,bi},变成ai<aj,按ai<aj排序即可。
③、设di > 0, dj > 0,即ai > bi, aj > bj,为满足式子min{ai,bj}<=min{aj,bi},则bi>bj,按bi>bj排序即可。
3、算法源码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct hand{ll a;ll b;ll d;
} h[20001];
ll c[20001];
bool cmp(hand h1,hand h2){if(h1.d != h2.d) return h1.d < h2.d;if(h1.d <= 0) return h1.a < h2.a;return h1.b > h2.b;
}
int main(){int T;cin >> T;while(T--){int n;cin >> n;for(int i = 1; i <= n; i++){cin >> h[i].a >> h[i].b;if(h[i].a > h[i].b) h[i].d = 1;else if(h[i].a == h[i].b) h[i].d = 0;else h[i].d = -1;}sort(h + 1, h + 1 + n, cmp);for(int i = 1; i <= n; i++){//因为前面已经排完序了,所以不需要用到单个a的值,所以可以用前缀和计算 h[i].a += h[i-1].a;c[i] = max(c[i-1],h[i].a)+ h[i].b;}cout << c[n] << endl;}}
贪心算法——皇后游戏(洛谷P2123)相关推荐
- 贪心算法——部分背包(洛谷 P2240)
贪心算法--部分背包问题 部分背包问题,顾名思义,部分 就是可以取一部分,也就是可以随意拆分的物品,是最简单经典的贪心问题. 解题步骤: 1)用结构体数组保存每个物品的价值及总重量.平均价值: 2)输 ...
- 深入理解 操作系统 SJF算法(以洛谷P1223题为例)
CPU Scheduling Algorithms 重要的CPU调度算法如下: FCFS Scheduling(First-Come, First-Served) SJF Scheduling(Sho ...
- 模拟——扫雷游戏(洛谷 P2670)
模拟算法指的是让程序完整地按照题目叙述的方式运行得到答案! 此题选自洛谷P2670 也是一道简单模拟的题,没有必要列举出8个if语句逐一判断8个方向, 只需要用一个二维数组来保存8个方向即可. 需要注 ...
- 深入理解 操作系统 LRU算法(以洛谷P1540题为例)
LRU算法 LeastRecentlyUsedLeast Recently UsedLeastRecentlyUsed 算法,意为"最近最少使用",这是操作系统内存管理部分重要的一 ...
- 广度优先搜索——好奇怪的游戏(洛谷 P1747)
题目选自洛谷P1747 简单的广搜模板题,4+8 = 12个方向进行bfs,目的地是(1,1) 每次查看队首是否到达,若到达(1,1) 则返回队首步长即可~ 需要注意的是,马走日和像走田的位置计算 i ...
- 深度优先搜索——八皇后问题(洛谷 P1219)
题目选自洛谷P1219 该题针对6-13皇后都行,只需改动输入的数字. 八皇后问题是经典的DFS问题,唯一需要注意的就是判断能够放置的条件,即满足什么状况是对的. 题目要求不能在同一行,同一列 ...
- 贪心算法——国王游戏
题目描述 孙悟空给花果山的小猴子们分桃子. 首先,他让每只小猴在左.右手上面分别写下一个整数,悟空自己也在左.右手上各写一个整数. 然后,让这 n 只小猴排成一排,悟空站在队伍的最前面. 排好队后,所 ...
- (快速幂算法+高精度)洛谷P1045 麦森数
前言 故事的最后,让我们以一道十分经典的题目--<麦森数>来结尾.接受现实吧,总会有我们没准备过的高精度运算出现.我们固然可以提前把高精度的快速幂模板也准备好,但是总会有百密一疏的时候 ...
- 图论算法——幻象迷宫(洛谷 P1363)
题目选自洛谷P1363 大概就是说给出一个01迷宫类的地图,按照这个地图来扩展新地图,类似这样 然后问你是不是###可以走无限远. ###那么,我们可以很清晰的意识到,如果可以从点(x,y)出发,达到 ...
- KMP算法小总结 洛谷P3375 【模板】KMP字符串匹配
提问:这里有一个长度为n的字符串str1和长度为m的字符串str2(n > = m),问在str1中str2出现了几次? 如果使用暴力求解,一个一个比较,在n和m都极大的情况下将花费非常多的不必 ...
最新文章
- java根据属性获取对象_java反射工具类--通过指定属性名,获取/设置对象属性值
- 第十五课.马尔科夫链蒙特卡洛方法
- Eslint中no-undef的检查报错
- 泛架构之于外包IT工程
- awk 分解行、字段
- win上mysql忘记root密码_MySQL数据库之windows下mysql忘记root密码的解决方法
- HTML页面提交TABLE
- Flash AS3.0中文帮助下载
- vscode中文_VS Code 中文社区正式成立啦!VS Code Day 圆满落幕!
- Looper对文件描述符的监控与处理
- ORB-SLAM2双目开源框架 (2) Tracking解析
- OpenEmu:一个让你在Mac上爽快体验任天堂的模拟器
- 在word中如何设置稿纸和字帖?学会帮你省下字帖钱哟!
- c语言int函数使用方法,int函数的使用方法_Excel中int函数的操作用法
- 蚂蚁金服测试开发实习面经
- 阿里云mysql空间不足_阿里云数据库MySQL系统文件导致实例空间满的解决办法
- 智能家居的春天来临 曾经共患难的集成商如今能同享福吗?
- Netty空闲检测之读空闲
- Flink实时数据处理实践经验(Flink去重、维表关联、定时器、双流join)
- 全局刷新和局部刷新的理解