ZOJ 2968 Difference Game 【贪心 + 二分】
2015-04-05 10:35
369 查看
题意: 有Ga、Gb两堆数字,初始时两堆数量相同。从一一堆中移一一个数字到另一一堆的花费定义为两堆之间数 量差的绝对值,初始时共有钱C。求移动后Ga的最小小值减Gb的最大大值可能的最大大值。 思路: 假如有足足够钱移动,那么Ga的最大大值和Gb的最小小值应该是两堆合并后排序中相邻的两数。那么我们 就枚举这个数。枚举的时候我们需要确定形成这个情况(大大的都在Ga堆,小小的都在Gb堆)的最少花 费,这个花费可以这样解决,假设Ga中向Gb中需要移入入ab个数,Gb需要向Ga移入入ba个数,首首先当 然是Ga移一一个给Gb,然后Gb移一一个给Ga,这样直到某一一堆需要移出都移出停止止,此时的花费就是 2*min(ab,ba)。接着就是其中一一堆一一直移给另一一堆,每移一一次费用用会增2,所以此时的花费为 |ab-ba|*(|ab-ba|-1)。总花费就为2*min(ab,ba) + |ab - ba| *(|ab -ba|- 1)。 当然可能没有足足够钱移动,Ga堆的最小小值永远小小于Gb堆的最大大值,这样我们当然要把Ga堆前C/2 (C/2+1)小小的移到Gb堆,Gb堆前C/2+1(C/2)的移到Ga堆,当然是交替移。 By @sake
Source Code:
//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <fstream> #include <cstring> #include <cmath> #include <stack> #include <string> #include <map> #include <set> #include <list> #include <queue> #include <vector> #include <algorithm> #define Max(a,b) (((a) > (b)) ? (a) : (b)) #define Min(a,b) (((a) < (b)) ? (a) : (b)) #define Abs(x) (((x) > 0) ? (x) : (-(x))) #define MOD 1000000007 #define pi acos(-1.0) using namespace std; int ga[20010], gb[20010], gc[50000]; bool cmp(const int & a, const int &b){ return a > b; } //二分查找,关键字key,右边界n,左边界默认-1 int b_search(int key, int n){ int l = -1, r = n, m; while (l+1 < r) { m = (l+r)/2; if (ga[m] < key) { l = m; } else { r = m; } } return r; } int main(){ int t; scanf("%d", &t);while (t--) { int n, cost; scanf("%d%d", &n, &cost); for (int i = 0; i < n; i ++) { scanf("%d", &ga[i]); gc[i] = ga[i]; } for (int i = 0; i < n; i ++) { scanf("%d", &gb[i]); gc[i+n] = gb[i]; } if (n == 1) { printf("%d\n", ga[0] - gb[0]); continue; } sort(ga, ga+n); sort(gc, gc+2*n); sort(gb, gb+n, cmp); int maxn = -50000; for (int i = 1; i < 2*n; i ++) { int ab = b_search(gc[i], n); int ba = (2*n - i) - (n - ab); int mab = min(ab, ba); int fab = abs(ab-ba); int c = 2*mab + (fab-1)*fab; if (c <= cost) { maxn = max(maxn, gc[i]-gc[i-1]); } } if (maxn > 0) { printf("%d\n", maxn); } else { int ans = max(ga[cost/2]-gb[cost/2+1], ga[cost/2+1]-gb[cost/2]); printf("%d\n", ans); } } return 0; }
相关文章推荐
- zoj 2968 Difference Game [贪心+二分]
- ZOJ 3820 Building Fire Stations (二分+贪心) 2014 牡丹江现场赛B
- ZOJ 2002 Copying Books 二分 贪心
- zoj 3820 Building Fire Stations(贪心 + 二分)
- zoj 3963 Heap Partition(并查集,贪心,二分)
- ZOJ 2002 Copying Books 二分 贪心
- ZOJ 3778 Talented Chef (贪心+二分)
- ZOJ 3090 Assemble(二分+贪心)
- zoj 2968 Difference Game (模拟)
- zoj-3963 Heap Partition(贪心+二分+树状数组)
- (ZOJ) 3334 二分+贪心(二分double的写法)
- ZOJ 3908 Number Game (贪心+二分+multiset)
- ZOJ 3963 Heap Partition( 并查集 + 贪心 +二分 )
- 浙江14届省赛 F.Heap Partition(ZOJ 3963)[贪心][二分]
- CF 329B(Biridian Forest-贪心-非二分)
- UVa 714 抄书(贪心+二分)
- ZOJ Problem Set - 3829Known Notation(贪心)
- POJ 2456 Aggressive cows(二分+贪心 计算个数)
- NYOJ 586 疯牛 & POJ 2456(二分搜索 + 贪心)
- poj3122 二分答案+贪心