有N只兔子,每只有一个血量B[i],需要用箭杀死免子。有M种不同类型的箭可以选择,每种箭对兔子的伤害值分别为D[i],价格为P[i](1 <= i <= M)。假设每种箭只能使用一次,每只免子也只能被射一次,计算要消灭地图上的所有兔子最少需要多少Q币。如不能杀死所有兔子,请输出No Solution。
特别说明:1、当箭的伤害值大于等于兔子的血量时,能将兔子杀死;2、血量B[i],箭的伤害值D[i],箭的价格P[i],均小于等于100000。
收起
兔子血量由大到小排个序,箭的攻击力由大到大小排个序,优先队列按照箭的价值从小到大,对于每个兔子,遍历所有箭,如果这支箭能杀死它,就入队,如果遍历完后队列为空,没有箭能杀死它,直接标记返回即可,这时没有结果,否则选择队头元素,就是杀死它的最便宜的箭,统计结果,将这支箭出队,下一个兔子不需要从头遍历所有箭,因为现在队列中的箭都能杀他,
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #define maxn 50005 using namespace std; int n,m; int a[maxn]; struct node { int d,p; bool operator<(const node&rhs)const { return p>rhs.p; } } b[maxn]; bool cmp1(node a,node b) { return a.d>b.d; } int main() { scanf("%d%d",&n,&m); if(n>m) {printf("No Solution\n"); return 0; } for(int i=1; i<=n; i++) scanf("%d",&a[i]); sort(a+1,a+n+1); for(int i=1; i<=m; i++) scanf("%d%d",&b[i].d,&b[i].p); sort(b+1,b+m+1,cmp1); priority_queue<node>q; int ans=0; int k=1; int flag=0; for(int i=n;i>=1;i--) { while(k<=m&&b[k].d>=a[i]) { q.push(b[k]); k++; } if(q.size()==0) { flag=1; break; } ans+=q.top().p; q.pop(); } if(flag) printf("No Solution\n"); else printf("%d\n",ans); return 0; }