题目大意:

给出n个人,每个人手里都有xi个金牌,yi个银牌,ci个铜牌。

你需要选出X个人,拿走他们手里的金牌,选出Y个人,拿走他们手里的银牌,选出Z个人,拿走他们手里的铜牌

X+Y+Z = n。并且选的这X,Y,Z个人里不能有重复的。

题解:

不妨先考虑只有金牌和银牌怎么做。

如果只有两种,就变成很简单的贪心了,依据每个人手中的金牌数x减去银牌数y然后排序,按差值选即可

现在又多了一个铜牌,我们还是按照这个思路

依据每个人手中的金牌数x减去银牌数y然后排序。

然后我们考虑如何分配我们的X和Y。

注意到,排完序以后,这里有一个奇妙的性质出现了

这个性质简单来说就是,银牌从排序靠前的元素选,金牌从排序靠后的元素选,这样做会更优

或者这样说,银牌和金牌的选择是互不交叉的。(考虑如果有交叉,那么相互交换一下会更优)

那么我们就可以这样求出答案

枚举一个k,从前k个元素中选出Y个银牌,从后n-k个元素中选出X个金牌,其他都是选铜牌

这样我们只需要把k从Y枚举到n-X就可以了

那铜牌的影响怎么处理呢?

就让金牌数和银牌数直接减去铜牌数,然后最后的答案加上铜牌数,这样所有的铜牌数就变成了0

就可以不考虑它的影响了。

对每一个k,答案就是前k个元素中最大的Y个银牌数和,加上后n-k个元素中最大的X个银牌数和

这个显然可以用set来维护。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <set>
#include <map>
#define fi first
#define se second
using namespace std;
const int maxn = 1e5 + ;
typedef pair<int, int> PII;
bool cmp(const PII &A, const PII &B){
return A.fi - A.se < B.fi - B.se;
}
PII a[maxn];
set<int> S[];
map<int, int> H[];
int ssz[], sz[];
long long ans = , temp, ans1[maxn], ans2[maxn];
void Erase(int x, int ty){
if(H[ty][x] == ) S[ty].erase(x);
H[ty][x]--;
ans -= x;
ssz[ty]--;
}
void Insert(int x, int ty){
if(H[ty][x] == ) S[ty].insert(x);
H[ty][x]++;
ans += x;
ssz[ty]++;
} void S_Insert(int x, int ty){
if(ssz[ty] == sz[ty]){
int y = *S[ty].begin();
if(y > x) return;
Erase(y, ty);
}
Insert(x, ty);
} int main()
{
int X, Y, Z, x, y, z;
cin>>X>>Y>>Z;
int n = X+Y+Z;
for(int i = ; i <= n; i++){
scanf("%d %d %d", &x, &y, &z);
x -= z;
y -= z;
ans += z;
a[i].fi = x;
a[i].se = y;
}
temp = ans;
ans = ;
sort(a+, a++n, cmp);
sz[] = Y; sz[] = X;
for(int i = ; i <= Y; i++) S_Insert(a[i].se, );
ans1[Y] = ans;
for(int i = Y+; i <= n-X; i++){
S_Insert(a[i].se, );
ans1[i] = ans;
}
ans = ;
for(int i = n; i >= n-X+; i--) S_Insert(a[i].fi, );
ans2[n-X+] = ans;
for(int i = n-X; i >= Y+; i--){
S_Insert(a[i].fi, );
ans2[i] = ans;
}
ans = -1e18;
for(int i = Y; i <= n-X; i++) ans = max(ans, ans1[i]+ans2[i+]);
cout<<ans+temp<<endl;
return ;
}

AGC018C Coins (set)的更多相关文章

  1. [LeetCode] Arranging Coins 排列硬币

    You have a total of n coins that you want to form in a staircase shape, where every k-th row must ha ...

  2. ACM: Gym 101047M Removing coins in Kem Kadrãn - 暴力

     Gym 101047M Removing coins in Kem Kadrãn Time Limit:2000MS     Memory Limit:65536KB     64bit IO Fo ...

  3. Codeforces 2016 ACM Amman Collegiate Programming Contest A. Coins(动态规划/01背包变形)

    传送门 Description Hasan and Bahosain want to buy a new video game, they want to share the expenses. Ha ...

  4. csuoj 1119: Collecting Coins

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1119 1119: Collecting Coins Time Limit: 3 Sec  Memo ...

  5. Coins

    Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One day Hi ...

  6. hdu 1398 Square Coins (母函数)

    Square Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  7. (混合背包 多重背包+完全背包)The Fewest Coins (poj 3260)

    http://poj.org/problem?id=3260   Description Farmer John has gone to town to buy some farm supplies. ...

  8. POJ3260The Fewest Coins[背包]

    The Fewest Coins Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6299   Accepted: 1922 ...

  9. POJ1742 Coins[多重背包可行性]

    Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 34814   Accepted: 11828 Descripti ...

随机推荐

  1. MySQL在同一表格里把字段值(value)给另一字段(name)

    在最近的窗帘项目中,我需要增加新的计价方法,其中就有一个是在后台输入价格的: 数据表: 购买页面 点击提交订单 那么我要算出有遮光衬布物品的价格,就必须知道我在后台设置的价格是多少 所以上代码: $i ...

  2. WebSocket协议 8 问

    WebSocket是一种比较新的协议,它是伴随着html5规范而生的,虽然还比较年轻,但大多主流浏览器都已经支持.它使用方面.应用广泛,已经渗透到前后端开发的各种场景中. 对http一问一答中二式流程 ...

  3. jQuery(二)事件

    鼠标事件: click dblclick mouseenter:鼠标进入 mouseleave:鼠标离开 hover:鼠标悬停 <!DOCTYPE html> <html> & ...

  4. tp5多条件查询

    ->where('m.user_nickname|w.nickname|c.companyname','like','%'.$search.'%')\

  5. C中 snprintf()函数的作用

    函数原型:int snprintf(char* dest_str,size_t size,const char* format,...); 函数功能:先将可变参数 “…” 按照format的格式格式化 ...

  6. (数据科学学习手札05)Python与R数据读入存出方式的总结与比较

    在数据分析的过程中,外部数据的导入和数据的导出是非常关键的部分,而Python和R在这方面大同小异,且针对不同的包或模块,对应着不同的函数来完成这部分功能: Python 1.TXT文件 导入: 以某 ...

  7. shell重温---基础篇(printf命令&test命令)

    在shell中还有一个输出的命令,那就是printf了.它模仿的是C程序库(library)里的printf()程序,是由POSIX标准所定义,所以嘞,使用printf脚本比echo移植性要好一点,它 ...

  8. java二分法来求一个数组中一个值的key

    package TestArray; import java.util.Arrays; /** * 二分法查找 */ public class Test { public static void ma ...

  9. awk用法介绍

    Awk 程序的结构如下: awk 'BEGIN{ print "start" } pattern { commands } END{ print "end" } ...

  10. 【算法】 string 转 int

    [算法] string 转 int 遇到的一道面试题, 当时只写了个思路, 现给出具体实现 ,算是一种比较笨的实现方式 public class StringToInt { /// <summa ...