思路:
贪心算法
1)把所有兔子的血量安从大到小排序,并且把箭的伤害从大到小排序
2)排序后,从第一只兔子开始,把每支能杀死该兔子的箭的价格放到一个小顶堆里
3)若堆不空,获得小顶堆的堆顶元素,删除之,直到所有兔子都能被射死或者找不到一支射死兔子的箭结束
代码如下:
#include <iostream>
#include <algorithm>
#include <set>
#include <queue>
using namespace std;
#define N 100010
typedef struct Node_
{
int d, p;
}Node;
Node Alice[N];
int rabbit[N];
__int64 heap[N];
int heaplen;
//当添加一个元素到数组末尾时,向上调整小顶堆,保证小顶堆特性:父节点值比其左右子树的值都要小
void adjustUp(__int64 heap[], int heaplen)
{
int p = heaplen, q = p / 2;
__int64 tmp = heap[heaplen];
while(q >= 1)
{
if(heap[q] < tmp)
{
break;
}
heap[p] = heap[q];
p = q;
q /= 2;
}
heap[p] = tmp;
}
//当删除堆顶元素时,最后一个元素放到堆顶,向下调节,保证小顶堆特性:父节点值比其左右子树的值都要小
void adjustDown(__int64 heap[], int heaplen)
{
__int64 tmp = heap[1];
int p = 1;
int q = 2 * p;
while(q <= heaplen)
{
if(q + 1 <= heaplen && heap[q+ 1] < heap[q])
{
++q;
}
if(heap[q] > tmp)
{
break;
}
heap[p] = heap[q];
p = q;
q *= 2;
}
heap[p] = tmp;
}
__int64 getMin(__int64 heap[], int &heaplen)
{
__int64 res = heap[1];
heap[1] = heap[heaplen--];
adjustDown(heap, heaplen);
return res;
}
void Insert(__int64 heap[], int& heaplen, __int64 key)
{
heap[++heaplen] = key;
adjustUp(heap, heaplen);
}
int rabbitCmp(int a, int b)
{
return a > b;
}
int cmp(Node a, Node b)
{
return a.d > b.d;
}
int main()
{
int t, i, j,n, m;
__int64 sum;
while(scanf("%d %d", &n, &m) != EOF)
{
for (i = 0;i < n; ++i)
{
scanf("%d", &rabbit[i]);
}
for (i = 0;i < m;++i)
{
scanf("%d",&Alice[i].d);
}
for (i = 0;i < m;++i)
{
scanf("%d",&Alice[i].p);
}
if (n > m)
{
printf("No\n");
continue;
}
heaplen = 0;
sort(rabbit, rabbit + n, rabbitCmp);
sort(Alice, Alice + m, cmp);
sum = 0;
j = 0;
priority_queue<int> m_que;
for (i = 0;i < n;++i)
{
while(j < m && Alice[j].d >= rabbit[i])
{
Insert(heap, heaplen, Alice[j].p);
++j;
}
if (heaplen >= 1)
{
sum += getMin(heap, heaplen);
}
else
{
break;
}
}
if (i < n)
{
printf("No\n");
}
else
{
printf("%I64d\n", sum);
}
}
return 0;
}