hdu 4544 湫湫系列故事——消灭兔子, 贪心算法+小顶堆

思路:

贪心算法

1)把所有兔子的血量安从大到小排序,并且把箭的伤害从大到小排序

2)排序后,从第一只兔子开始,把每支能杀死该兔子的箭的价格放到一个小顶堆里

3)若堆不空,获得小顶堆的堆顶元素,删除之,直到所有兔子都能被射死或者找不到一支射死兔子的箭结束

代码如下:

#include 
#include 
#include 
#include 
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 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;
}


你可能感兴趣的:(c/c++,acm算法)