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\n");
}
else
{
printf("%I64d\n",ans);
}
}
return 0;
}