2020牛客寒假算法基础集训营2——F.拿物品【思维 + 贪心】

题目传送门


题目描述

牛牛和 牛可乐 面前有 n 个物品,这些物品编号为 1 , 2 , , n 1,2,\dots,n ,每个物品有两个属性 a i , b i a_i, b_i

牛牛与 牛可乐会轮流从剩下物品中任意拿走一个, 牛牛先选取。

设 牛牛选取的物品编号集合为 H,牛可乐选取的物品编号的集合为 T,取完之后,牛牛 得分为 i H a i \sum_{i\in H} a_i ;而 牛可乐得分为 i T b i \sum_{i\in T} b_i

牛牛和 牛可乐都希望自己的得分尽量比对方大(即最大化自己与对方得分的差)。

你需要求出两人都使用最优策略的情况下,最终分别会选择哪些物品,若有多种答案或输出顺序,输出任意一种。


输入描述:

第一行,一个正整数 n,表示物品个数。
第二行,n 个整数 a 1 , a 2 , , a n a_1,a_2,\dots,a_n ,表示 n 个物品的 A 属性。
第三行,n 个整数 b 1 , b 2 , , b n b_1,b_2,\dots,b_n ,表示 n 个物品的 B 属性。
保证 2 n 2 × 1 0 5 0 a i , b i 1 0 9 2\leq n\leq 2\times 10^5 ,0\leq a_i,b_i\leq 10^9


输出描述:

输出两行,分别表示在最优策略下 牛牛和 牛可乐各选择了哪些物品,输出物品编号。


输入

3
8 7 6
5 4 2


输出

1 3
2


说明

3 1
2
也会被判定为正确


题解

  • 假设物品已经被选完,此时 牛牛选择的物品 A 属性的价值和是 N , 牛可乐选择的物品 BB 属性价值和是 M 。

  • 如果 牛牛的 ( a 1 , b 1 ) (a_1,b_1) 物品与 牛可乐的 ( a 2 , b 2 ) (a_2,b_2) 交换,则 N = N a 1 + a 2 , M = M + b 1 b 2 N'=N-a_1+a_2, M'=M+b_1-b_2 ,对于 牛牛(目标是最大化 N M N-M )来说会变得更优仅当 a 1 + b 1 < a 2 + b 2 a_1+b_1<a_2+b_2 N M > N M N'-M'>N-M 化简就能得到),对于 牛可乐也一样。所以两人都会优先选择 a i + b i a_i+b_i 最大的物品。

  • 将物品按照两个属性的和从大到小排序,依次分给两人即可。

  • 除排序时间复杂度 O ( n ) O(n)


AC-Code

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 7;
struct Node {
	int a, b, i;
	bool operator < (Node t)const {
		return t.a + t.b < a + b;
	}
}node[maxn];
int main() {
	int n;	cin >> n;
	for (int i = 0; i < n; ++i)	node[i].i = i+1, cin >> node[i].a;
	for (int i = 0; i < n; ++i)	cin >> node[i].b;
	sort(node, node + n);

	cout << node[0].i;
	for (int i = 2; i < n; i += 2)
		cout << " " << node[i].i;
	cout << endl << node[1].i;
	for (int i = 3; i < n; i += 2)
		cout << " " << node[i].i;
	cout << endl;
}
发布了157 篇原创文章 · 获赞 99 · 访问量 9811

猜你喜欢

转载自blog.csdn.net/Q_1849805767/article/details/104213584