USACO07DEC 美食的食草动物 Gourmet Grazers

思路

应该可以发现,这题可以用贪心。有两个值需要满足比较麻烦,我们考虑对询问和牧草按照口感(绿色值)排序。这样,对于一个询问(Ai,Bi),只要从口感大于等于Bi的牧草中选出价格最小的且大于等于Ai的牧草,这样可以证明是最优的。如果没有符合条件的牧草,就是无解。

用multiset来维护牧草的价格很方便,支持所有操作,当然价格可以重复。时间复杂度$O(N\log N)$

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
pair<int,int> cow[N],grass[N];
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>cow[i].second>>cow[i].first;
	sort(cow+1,cow+n+1);
	for(int i=1;i<=m;i++)
		cin>>grass[i].second>>grass[i].first;
	sort(grass+1,grass+m+1);
	multiset<int> S;
	int j=m;
	long long ans=0;
  //注意用64位整数保存结果
	for(int i=n;i;i--)
	{
		for(;j&&grass[j].first>=cow[i].first;j--)
			S.insert(grass[j].second);
      //插入口感满足要求的牧草
		multiset<int>::iterator it=S.lower_bound(cow[i].second);
      //找到第一个价格的大于等于Ai的牧草
		if(it==S.end())
		{
			cout<<-1<<endl;
			return 0;
		}
		ans+=*it;
		S.erase(it);
      //别忘了删除
	}
	cout<<ans<<endl;
	return 0;
}