题解 | GourmetGrazers-牛客假日团队赛6K题

K-Gourmet Grazers_牛客假日团队赛6

https://ac.nowcoder.com/acm/contest/993/K

题目描述

Like so many others, the cows have developed very haughty tastes and will no longer graze on just any grass. Instead, Farmer John must purchase gourmet organic grass at the Green Grass Grocers store for each of his cows.
Each cow i demands grass of price at least and with a greenness score at least . The GGG store has different types of grass available, each with a price and a greenness score of . Of course, no cow would sacrifice her individuality, so no two cows can have the same kind of grass.
Help Farmer John satisfy the cows' expensive gourmet tastes while spending as little money as is necessary.

输入描述:

* Line 1: Two space-separated integers: N and M.
* Lines 2..N+1: Line i+1 contains two space-separated integers: and
* Lines N+2..N+M+1: Line i+N+1 contains two space-separated integers: and

输出描述:

* Line 1: A single integer which is the minimum cost to satisfy all the cows. If that is not possible, output -1.

示例1

输入
4 7
1 1
2 3
1 4
4 2
3 2
2 1
4 3
5 2
5 4
2 6
4 4
输出
12
说明
Cow 1 eats grass 2 at cost 2, cow 2 eats grass 3 at cost 4, cow 3 eats grass 6 at cost 2, and cow 4 eats grass 7 at cost 4, for a total cost of 12.

解答

贪心+multiset
本题每一头奶牛有两个标准来找到它合适的牧草。为了使花费最小,当然是选择的两个参数值越小越好。
而且这两个参数是绑定在一起的,所以考虑用pair存数据(pair在库里别忘了qwq)。
首先找到最小符合的牧草,再把这个牧草相关数据从set里删除。
我们可以以其中一个参数为主关键字,按要求从高到低来处理奶牛的要求,每当现在指针所指的牧草能够满足要求,我们就把它的另一参数加入我们的multiset中,加入完成之后multiset会自动维护好当前的最优值。倒着处理可以避免预先加入了不合当前奶牛要求的牧草,保证了正确性,从而降低了处理的代码复杂度。
这里维护有一个也不能说上是技巧的小技巧:
因为我们的pair是默认以first为主关键字升序排序的,而我们要求输出的是其中一个参数:价格的和。因为我们在操作中是把两个参数的一个参数加入multiset维护,所以显而易见的,要得到所有选取的牧草的价格,我们只要把牧草变为pair中的second就可以了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
#include <algorithm>
#include <utility>
typedef long long LL;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
    return x*f;}
const int N=101000;
int n,m;
std::pair<int,int> cow[N],grass[N];
using namespace std;
int main(){
    int i,j;
    n=read();m=read();
    for (i=1;i<=n;++i){cow[i].second=read();cow[i].first=read();}
    sort(cow+1,cow+n+1);
    for (i=1;i<=m;++i){grass[i].second=read();grass[i].first=read();}
    sort(grass+1,grass+m+1);
    multiset<int> G;j=m;LL ans=0;
    for (i=n;i>=1;--i){
        for (;j&&(grass[j].first>=cow[i].first);--j) G.insert(grass[j].second);
        multiset<int>::iterator iter;
        iter=G.lower_bound(cow[i].second);//因为默认以first为主关键字 
        if (iter==G.end()) {puts("-1");return 0;}
        ans+=(*iter);G.erase(iter);
    }
    printf("%lld\n",ans);
    return 0;
}

来源:KAMIKI_横
全部评论

相关推荐

拒绝996的悲伤蛙:此贴终结|给路过的牛友分享一下心得👇 实习的时候不要光埋头干活,身边的大佬同事才是真·宝藏人脉!大胆请教他们工作以及职场上的问题以我的经历,我的带教有十几年工作经验,做过运维、后端开发、web测试,现在是高级软测,是行走的避坑指南 我之前纠结要不要学Web测试简历,被他一句话点醒:Web发展成熟,岗位需求在缩,AI对互联网的冲击可能以后架构+开发+测试一人包揽。现在用户更多用的是移动端APP/小程序,相比之下天天守着电脑刷网页的人基数小。 这里我的纠结得到反馈,于是我又把简历发给带教,获得了一对一的简历指导。 感兴趣的可以看看: 1.教育背景:本科→本科(全日制) 2.实习经历:总体问题不大,但第2点要稍作修改,可以写但做功课,如风机、水箱……可能会问用哪个供应商的?使用寿命、型号、电压电流、多少秒会触发逻辑? 3.项目经历(坑太多,大型翻车现场): - 项目名越直白越好,让人一眼就知道你干了啥。 -用的什么语言设计核心接口,异步执行做功课,涉及线程问题,被问可回答n个功能是如何错开异步执行的 - “验证任务消费……阻塞丢包”“高负载稳定性”这种词,没三五年开发功底不要写,不然面试时被问线程、数量级、CPU占用,内存带宽等影响性能的直接原地社死。 -做功课 -做功课,测了哪些模块,如何设计,接口流量抓包,token,变量…… -做功课,要熟悉网络协议…… 带教之前做互联网开发的时候面试过很多人,总的来说不要为了显得项目高大上过渡包装,写了就要做好拷打的准备
听劝,我这个简历该怎么改...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务