1. 程式人生 > 實用技巧 >【POJ3614 Sunscreen】【貪心】

【POJ3614 Sunscreen】【貪心】

題面:

有c頭牛,需要的亮度在[min_ci,max_ci]中,有n種藥,每種m瓶,可以使亮度變為v 問最多能滿足多少頭牛

演算法

我們自然考慮貪心,我們首先對每頭牛的min進行排序,然後對於每種藥,將min<v的牛拿出來討論
我們自然會先把藥給max較小的牛來使用 max較大的留到後面 這樣有更大的可能性,且不會丟失最優解

程式碼

實現上的一些問題在註釋裡

#include<iostream>
#include<cstdio>
#include <queue>
#include<algorithm>
#define MAXN 2555
#define INF 1000000007
#define ll long long
using namespace std;
ll c,n;
typedef pair<ll,ll> QWQ;//定義一個型別pair 
QWQ cow[MAXN],scr[MAXN];
priority_queue<ll>QAQ;
int main()
{
	scanf("%lld%lld",&c,&n);
	for(ll i = 1;i <= c;i++)scanf("%lld%lld",&cow[i].first,&cow[i].second);
	for(ll i = 1;i <= n;i++)scanf("%lld%lld",&scr[i].first,&scr[i].second);
	sort(cow + 1,cow + 1 + c);
	sort(scr + 1,scr + 1 + n);
	ll now = 1,ans = 0;
	for(ll i = 1;i <= n;i++)
	{
		for(;now <= c && cow[now].first <= scr[i].first;now++)//將min<v的牛拿出來考慮 
		QAQ.push(-cow[now].second); //max較小的在前 這裡用相反數建立小根堆 
		while(!QAQ.empty()&&scr[i].second)//這瓶藥是否能用 
		{
			ll x = -QAQ.top();
			QAQ.pop();
			if(x >= scr[i].first)
			{
				ans ++;
				scr[i].second--;
			}
		}
	}
	cout<<ans;
	return 0;
}