bzoj1572 [Usaco2009 Open]工作安排Job【贪心 堆】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1572
尽管这一题没有看题解,但是耗时还是比本应耗费的时间要长,所以还是写一下,以提升经验
这一题一看就是贪心,贪心最常用的数据结构就是堆,单调栈,单调队列。尽管想到了这,但是之后脑子就卡壳了,怎么都想不出来。。。
这一题的真谛就是“能选就选,不能选就尝试换”,怎么理解呢?首先先按结束时间排序。每选一个,就把它扔进小根堆里。如果时间允许,当然就选啦。如果时间不允许,就对比堆顶的利润是否比当前这个小,若小,果断弹出,选当前这个。这样子,总时间没变,但是利润增加了。
#include <cstdio> #include <algorithm> #include <queue> const int maxn = 100005; int n, now; long long ans; struct st1 { long long d, p; } a[maxn]; struct st2 { long long data; bool operator<(const st2 rhs) const { return data > rhs.data; } }; std::priority_queue<st2> hp; bool cmp(const st1 & aa, const st1 & ss) { return aa.d < ss.d; } int main(void) { //freopen("in.txt", "r", stdin); scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%lld%lld", &a[i].d, &a[i].p); } std::sort(a + 1, a + n + 1, cmp); for (int i = 1; i <= n; ++i) { if (now < a[i].d) { ans += a[i].p; ++now; hp.push((st2){a[i].p}); } else if (a[i].p > hp.top().data) { ans += a[i].p - hp.top().data; hp.pop(); hp.push((st2){a[i].p}); } } printf("%lld\n", ans); return 0; }
希望下一次做这种(水)题能快一点想到。。。