当前位置: 代码迷 >> 综合 >> 【51NOD-1191-消灭兔子】优先队列+贪心
  详细解决方案

【51NOD-1191-消灭兔子】优先队列+贪心

热度:44   发布时间:2023-12-29 02:33:27.0

51NOD1191消灭兔子
题意
就是有n只生命值不同的兔子,有m支不同的箭就是有n只生命值不同的兔子,有m支不同的箭nm
每种箭有不同的伤害和花费,每个兔子只能被射一次,每支箭只能用一次每种箭有不同的伤害和花费,每个兔子只能被射一次,每支箭只能用一次
求杀死所有兔子的最小花费。求杀死所有兔子的最小花费。
做法
由于每只兔子只能被射一次,每支箭只能用一次由于每只兔子只能被射一次,每支箭只能用一次
我们就可以将箭按杀伤力降序排序,将兔子生命值按降序排序我们就可以将箭按杀伤力降序排序,将兔子生命值按降序排序
然后将所有能杀死当前兔子的箭丢进价值小优先的优先队列,然后双指针不断杀死每只兔子即可。然后将所有能杀死当前兔子的箭丢进价值小优先的优先队列,然后双指针不断杀死每只兔子即可。
代码

#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;
}