题解 CF934A 【A Compatible Pair】 ——贪心
题意:
给定两个数列 \(A\) 、 \(B\) ,元素个数分别为 \(n\) , \(m\) \((2 \le n,m \le 50)\) 。数列中所有元素大小均在 \(-10^{9}\) 到 \(10^{9}\) 之间。
现要求在 \(A\) 数列中删掉一个元素,使得 \(A\) 中任一元素和 \(B\) 中任一元素相乘的共 \((n-1) \times m\) 种可能的值中的最大值最小。输出该最大值。
题解:
其实这题的 \(n, m\) 都可以开大到 \(10^6\)。
我的做法是 \(O(n+m)\) 的贪心。
先考虑不拿走元素的情况。那么对答案有贡献的元素只有可能是 \(A,B\) 中最大的元素和最小的元素。可以证明。
假设在 \(B\) 中挑了一个元素的值为 \(k\),那么最终得出的这个值 \(y\) 与在 \(A\) 中挑出的元素 \(x\) 成正比例关系:\(y = kx\)。
这时候可以分类:
当 \(k>0\) 时,\(y\) 随 \(x\) 的增大而增大。所以当 \(x\) 取最大值时,\(y\) 才会是最大值。
当 \(k=0\) 时,无论 \(x\) 取何值,\(y\) 的值都为 \(0\)。此时我们可以当做取了最大值或最小值。
当 \(k<0\) 时,\(y\) 随 \(x\) 的增大而减小。所以当 \(x\) 取最小值时,\(y\) 才会是最大值。
终上所述,当 \(x\) 取最大值或最小值时,\(y\) 存在最大值。
所以我们应该挑 \(A\) 中最大或最小的元素。\(B\) 同理。
那么 \(y\) 的最大值为 \(\max(Max_A \cdot Max_B, Max_A \cdot Min_B, Min_A \cdot Max_B, Min_A \cdot Min_B)\)。
有 \(Max_A \cdot Max_B\) 和 \(Min_A \cdot Min_B\) 很好想到,那么为什么还要 \(Max_A \cdot Min_B\) 和 \(Min_A \cdot Max_B\) 呢?
有一组数据:
3 3
-3 -2 -1
1 2 3
显然答案一定是负数,为了使答案最大,这个值的绝对值应该越小。这样,就出现了 \(Max_A \cdot Min_B\) 了。
再考虑删除的情况。为了删除后的最大值最小,肯定拿走的数要对答案有贡献,那么就一定是 \(Max_A\) 或者 \(Min_A\)。此时 \(Maxer_A\) 和 \(Miner_A\) 就分别成为了 \(A\) 的最大值和 \(A\) 的最小值。再分别拿走 \(Max_A\)、\(Min_A\),并分别用 \(Maxer_A\)、\(Miner_A\) 代替,代入上方公式,取较小值,就是最后答案了。
最大值、次大值、最小值、次小值在输入时就可以求出,不需要再花费 \(n log n\) 的排序,也可以节省空间。
时间复杂度仅有 \(O(n+m)\)。
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long llt;
const llt INF = 0x7F7F7F7F7F7F7F7F;
int n, m;
llt Max1 = -INF, Maxer1 = -INF, Min1 = INF, Miner1 = INF, Max2 = -INF, Min2 = INF;
void init() {
scanf("%d %d", &n, &m);
}
void solve() {
for (int i = 1; i <= n; ++i) {
llt x;
scanf("%lld", &x);
if (x > Max1) {
Maxer1 = Max1;
Max1 = x;
} else if (x > Maxer1)
Maxer1 = x;
if (x < Min1) {
Miner1 = Min1;
Min1 = x;
} else if (x < Miner1)
Miner1 = x;
}
for (int i = 1; i <= m; ++i) {
llt x;
scanf("%lld", &x);
Min2 = min(Min2, x);
Max2 = max(Max2, x);
}
//拿走值最大的元素
llt ans1 = max( max(Maxer1 * Max2, Maxer1 * Min2), max(Min1 * Max2, Min1 * Min2) );
//拿走值最小的元素
llt ans2 = max( max(Max1 * Max2, Max1 * Min2), max(Miner1 * Max2, Miner1 * Min2) );
llt ans = min(ans1, ans2);
printf("%lld\n", ans);
}
int main() {
init();
solve();
return 0;
}
题解 CF934A 【A Compatible Pair】 ——贪心的更多相关文章
- CF934A A Compatible Pair
A Compatible Pair time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- CF934A A Compatible Pair 题解
Content 有两个数列 \(A\) 和 \(B\),\(A\) 数列里面有 \(n\) 个元素,\(B\) 数列里面有 \(m\) 个元素,现在请从 \(A\) 数列中删除一个数,使得 \(A\) ...
- 【题解】P1712 [NOI2016]区间(贪心+线段树)
[题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...
- Codeforces 934.A A Compatible Pair
A. A Compatible Pair time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Codeforces Round #462 (Div. 2) A Compatible Pair
A. A Compatible Pair time limit per test1 second memory limit per test256 megabytes Problem Descript ...
- 【题解】Cut the Sequence(贪心区间覆盖)
[题解]Cut the Sequence(贪心区间覆盖) POJ - 3017 题意: 给定一大堆线段,问用这些线段覆盖一个连续区间1-x的最小使用线段的数量. 题解 考虑一个这样的贪心: 先按照左端 ...
- Codeforces 934 A.Compatible Pair
http://codeforces.com/contest/934 A. A Compatible Pair time limit per test 1 second memory limit p ...
- 【题解】[HNOI2015]菜肴制作(贪心+topo序)
[题解][HNOI2015]菜肴制作(贪心+topo序) 题意:请你构造一个排列\(p[i]\)使得对于数组\(arc[i]=p[i]\)的字典序最小,并且对于给定的有序数对\((u,v)\)保证你给 ...
- 【题解】P4755 Beautiful Pair(启发式合并的思路+分治=启发式分治)
[题解]P4755 Beautiful Pair upd: 之前一个first second烦了,现在AC了 由于之前是直接抄std写的,所以没有什么心得体会,今天自己写写发现 不知道为啥\(90\) ...
随机推荐
- linux touch命令 创建文件
touch 创建文件,用法,touch test.txt,如果文件存在,则表示修改当前文件时间 [root@MongoDB ~]# touch /data/text.txt [root@MongoDB ...
- IP代理网址
http://www.kuaidaili.com/free/ http://www.66ip.cn/ http://www.xicidaili.com/nn/ http://www.ip3366.ne ...
- Spark SQL 编程初级实践
一.实验目的 (1) 通过实验掌握 Spark SQL 的基本编程方法: (2) 熟悉 RDD 到 DataFrame 的转化方法: (3) 熟悉利用 Spark ...
- Linux的发展历史
创始人: linux操作系统由林纳斯·本纳第克特·托瓦兹编写而成,是管理电脑硬件以及运行电脑软件的操作系统. 创始发展过程:Linux操作系统的诞生.发展和成长过程始终依赖着五个重要支柱:UNIX 操 ...
- flask 虚拟换将安装
1.1. 1.4虚拟环境的安装 1.1.1. 安装虚拟环境 1.1.1.1. 安装 注意:这里必须使用pip3 安装. sudo pip3 install virtualenv sudo pip3 ...
- day1:java学习第一天之eclipse安装
选择开发语言的学习其实不用纠结,如果你说自己是做开发的,连最流行的开发语言都不会,好像说不过去,并且最流行也说明用的人多,优秀的人也会,自己要提高要多向优秀的人学习.想明白这点其实选择就好说了,再一个 ...
- Oracle exp和expdp对数据进行备份
以下给出两个示例,详细内容需要查阅手册: exp system OWNER=ZLTX FILE=ZLTX20190123.DMP expdp system DUMPFILE=ZLTX20190123. ...
- php读取和导出Excel文件
require 'vendor/PHPExcel/PHPExcel.php';require 'vendor/PHPExcel/PHPExcel/IOFactory.php'; public func ...
- linux 命令 jps 和 goassess
jps (Java Virtual Machine Process Status Tool) 是java提供的一个显示当前所有java进程pid的命令,适合在linux/unix平台上简单察看当前j ...
- 如何查看视图的sql语句
select text from syscomments s1 join sysobjects s2 on s1.id=s2.id where name='视图名称'前提条件是视图没有被加密,有权限