bzoj 1691 [Usaco2007 Dec]挑剔的美食家 贪心+multiset

题面

题目传送门

解法

显然,每一头牛肯定是尽量选取最接近自己的那一份
考虑将牛的需求和干草分别按照第二关键字排序
求解第 i i 头奶牛的时候先将所有第二关键字不小于它的干草加进一个multiset里面
然后找它价格的后继就可以了
时间复杂度:O(nlog n)

代码

#include <bits/stdc++.h>
#define int long long
#define N 100010
using namespace std;
template <typename node> void chkmax(node &x, node y) {x = max(x, y);}
template <typename node> void chkmin(node &x, node y) {x = min(x, y);}
template <typename node> void read(node &x) {
    x = 0; int f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar(); x *= f;
}
struct Node {
    int x, y;
    bool operator < (const Node &a) const {
        return y > a.y; 
    }
} a[N], b[N];
main() {
    int n, m; read(n), read(m);
    for (int i = 1; i <= n; i++) read(a[i].x), read(a[i].y);
    for (int i = 1; i <= m; i++) read(b[i].x), read(b[i].y);
    sort(a + 1, a + n + 1), sort(b + 1, b + m + 1);
    multiset <int> s; int ans = 0;
    for (int i = 1, cur = 1; i <= n; i++) {
        while (b[cur].y >= a[i].y && cur <= m) s.insert(b[cur].x), cur++;
        if (s.lower_bound(a[i].x) == s.end()) {cout << "-1\n"; return 0;}
        ans += *s.lower_bound(a[i].x), s.erase(s.lower_bound(a[i].x));
    }
    cout << ans << "\n";
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值