http://acm.hdu.edu.cn/showproblem.php?pid=4544
这个题用优先队列做旧很简单了,但是我只会队列,但不会优先队列,还要努力学习C++里面的重载。。T_T。。
思路就是对兔子的血量先进行排序,然后对剑的杀伤力排序,然后用优先队列,弹出能杀死兔子但是价格又是最低的那个箭。
直接看代码把。。
AC代码:
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #define N 100005 using namespace std; struct Node { int d,p; bool operator < (const Node &a)const //在队列里出队时按<出队,这里是按从大到小排序。则出队时输出p最小值 { return p>a.p; } }b[N]; /*这种重载也是可以的 struct Node { int d,p; friend bool operator < (Node a, Node b) //在队列里出队时按<出队,这里是按从大到小排序。则出队时输出p最小值 { return a.p>b.p; } }b[N]; */ int a[N]; //每只兔子的血量 bool cmp1(int a, int b) { return a>b; } bool cmp2(Node a, Node b) { return a.d > b.d; } int main() { int n,m,i; int res; int flag; //标记看是否能全部杀死兔子 __int64 ans; //存最小金钱 while(scanf("%d%d",&n,&m)!=EOF) { priority_queue<Node> q; //定义优先队列 for(i = 0; i < n; i++) //输入兔子的血量 { scanf("%d",&a[i]); } for(i = 0; i < m; i++) //输入每把箭的伤害值 { scanf("%d",&b[i].d); } for(i = 0; i < m; i++) //相应每把箭的价格 { scanf("%d",&b[i].p); } sort(a,a+n,cmp1); //把兔子血量从大到小排序 sort(b,b+m,cmp2); //把箭的杀伤力从大到小排序 res = ans = flag = 0; for(i = 0; i < n; i++) //看是找能否杀死第i个兔子 { while(res < m && b[res].d >= a[i]) //入队所有能一次杀死兔子的箭 { q.push(b[res]); res++; } if(q.empty()) //如果队列里面没有箭则无法杀死兔子,直接退出 { flag = 1; break; } else { Node u=q.top(); ans+=u.p; //总金钱加上队头的钱 q.pop(); //出队 } } if(flag == 1) { printf("No "); } else { printf("%I64d ",ans); } } return 0; }