1. 程式人生 > >【51NOD-1191-消滅兔子】優先佇列+貪心

【51NOD-1191-消滅兔子】優先佇列+貪心

51NOD1191消滅兔子
題意
n

m
就是有n只生命值不同的兔子,有m支不同的箭
每種箭有不同的傷害和花費,每個兔子只能被射一次,每支箭只能用一次

求殺死所有兔子的最小花費。
做法
由於每隻兔子只能被射一次,每支箭只能用一次
我們就可以將箭按殺傷力降序排序,將兔子生命值按降序排序
然後將所有能殺死當前兔子的箭丟進價值小優先的優先佇列,然後雙指標不斷殺死每隻兔子即可。
程式碼

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 5e4+10;
int B[maxn];
struct data
{
    int d,p;
}x[maxn];
bool cmp(const data &a,const data &b)
{
    return a.d>b.d;
}
struct node
{
    int d,p;
    node(int dd,int pp)
    {
        d=dd;
        p=pp;
    }
    friend bool operator < (node a, node b)
    {
        return a.p>b.p;//結構體中,x小的優先順序高
    }
};
priority_queue<node>pq;
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)  scanf("%d",&B[i]);
    for(int i=1;i<=m;i++)  scanf("%d%d",&x[i].d,&x[i].p);
    sort(B+1,B+1+n);
    sort(x+1,x+1+m,cmp);
    int pos=1;
    int cnt=0;
    long long  ans=0;
    for(int i=n;i>=1;i--)
    {
        while(pos<=m&&x[pos].d>=B[i])
        {
            pq.push(node(x[pos].d,x[pos].p));
            pos++;
        }
        if(pq.empty()) break;
        else
        {
            cnt++;
            node tmp=pq.top();
            pq.pop();
            ans+=tmp.p;
        }
    }
    if(cnt==n)
    {
        printf("%lld\n",ans);
    }
    else
    {
        printf("No Solution\n");
    }
    return 0;
}