51nod 1191 消灭兔子(优先队列好题)

来源:互联网 发布:iphone数据恢复教程 编辑:程序博客网 时间:2024/05/16 14:48

这里写图片描述
一开始的想法是用二分图贪心来做,结果T了。然后想了想,可以用优先队列来做。
先按兔子的血量从小到大排序,同时箭的伤害从小到大排序。枚举每一只兔子i,找出第一支能杀死它的箭,从这支箭往前到第一支能杀死第i-1兔子的箭都能杀死前i-1只兔子。把这些放入优先队列,去前i-1小的值。再把这只箭放入优先队列。

#include<cstdio>#include<vector>#include<algorithm>#include<cstring>#include<queue>using namespace std;const int maxn = 1e5;long long a[maxn], ans;int link[maxn], n, m;int used[maxn];struct p{    long long kill, val;}w[maxn];int cmp(p a, p b){    return a.val < b.val;}int cmp1(p a, p b){    return a.kill < b.kill;}int main(){    priority_queue<int, vector<int>, less<int> > q;    scanf("%d%d", &n, &m);    for(int i = 1; i <= n; i++){        scanf("%lld", &a[i]);    }    for(int i = 1; i <= m; i++){        scanf("%lld%lld", &w[i].kill, &w[i].val);    }    sort(a + 1, a + n + 1);    sort(w + 1, w + 1 + m, cmp1);    if(w[m].kill < a[n]) {        puts("No Solution");        return 0;    }    int j = 1;    for(int i = 1; i <= n; i++){        while(w[j].kill < a[i] && j <= m){            q.push(w[j].val);            j++;        }        while(!q.empty() && q.size() > i - 1) q.pop();        if(j > m) break;        q.push(w[j].val);        j++;    }    while(j <= m && w[j].kill > a[n]) q.push(w[j].val), j++;    while(q.size() > n) q.pop();    int tot = 0;    while(!q.empty()){        ans += q.top();        q.pop();        tot++;    }    if(tot == n) printf("%lld\n", ans);    else puts("No Solution");    return 0;}
原创粉丝点击