1191 消灭兔子(贪心+优先队列)
Posted happy_code
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1191 消灭兔子(贪心+优先队列)相关的知识,希望对你有一定的参考价值。
有N只兔子,每只有一个血量B[i],需要用箭杀死免子。有M种不同类型的箭可以选择,每种箭对兔子的伤害值分别为D[i],价格为P[i](1 <= i <= M)。假设每种箭只能使用一次,每只免子也只能被射一次,计算要消灭地图上的所有兔子最少需要多少Q币。如不能杀死所有兔子,请输出No Solution。
特别说明:1、当箭的伤害值大于等于兔子的血量时,能将兔子杀死;2、血量B[i],箭的伤害值D[i],箭的价格P[i],均小于等于100000。
Input
第1行:两个整数N,M,中间用空格分隔(1 <= N, M <= 50000),分别表示兔子的个数和箭的种类。
第2 - N + 1行:每行1个正整数(共N行),表示兔子的血量B[i](1 <= B[i] <= 100000)。
第N + 2 - N + M + 1行:每行2个正整数(共M行),中间用空格分隔,表示箭所能造成的伤害值D[i],和需要花费的Q币P[i](1 <= D[i], P[i] <= 100000)。
Output
输出最少需要多少Q币才能消灭所有的兔子。如果不能杀死所有兔子,请输出"No Solution"。
Input示例
3 3
1
2
3
2 1
3 2
4 3
Output示例
6
一只兔子只能射一箭,一下子就简单了,将兔子按血量降序排序,将箭按伤害降序排序,然后用个优先队列贪心选择最小价值的箭杀每只兔子ok,
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define INF 0x3f3f3f3f 4 #define LL long long 5 #define MOD 1000000007 6 #define MX 50005 7 struct Arrow 8 { 9 int d, p; 10 bool operator < (const Arrow &b)const{ 11 return p>b.p; 12 } 13 }arr[MX]; 14 15 int n,m; 16 priority_queue<Arrow> Q; 17 int tu[MX]; 18 19 bool cmp1(int &a,int &b){ 20 return a>b; 21 } 22 bool cmp2(Arrow &a,Arrow &b){ 23 return a.d>b.d; 24 } 25 26 int main() 27 { 28 scanf("%d%d",&n,&m); 29 for (int i=1;i<=n;i++) 30 scanf("%d",&tu[i]); 31 sort(tu+1,tu+1+n,cmp1); 32 for (int i=1;i<=m;i++) 33 scanf("%d%d",&arr[i].d,&arr[i].p); 34 sort(arr+1,arr+1+m,cmp2); 35 36 int pos =1; // 多少箭入队 37 int ok=1; 38 LL ans=0; 39 while (pos<=m) 40 { 41 if (arr[pos].d>=tu[1]) 42 { 43 Q.push(arr[pos]); 44 pos++; 45 } 46 else break; 47 } 48 for (int i=1;i<=n;i++) 49 { 50 if (i>1&&tu[i]!=tu[i-1]) 51 { 52 while (pos<=m) 53 { 54 if (arr[pos].d>=tu[i]) 55 { 56 Q.push(arr[pos]); 57 pos++; 58 } 59 else break; 60 } 61 } 62 if (Q.empty()) 63 { 64 ok=0; 65 break; 66 } 67 ans+=Q.top().p;; 68 Q.pop(); 69 } 70 if (ok) 71 printf("%lld\n",ans); 72 else 73 printf("No Solution\n"); 74 return 0; 75 }
以上是关于1191 消灭兔子(贪心+优先队列)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1029: [JSOI2007]建筑抢修优先队列+贪心策略