题意:每一头牛有一个接受的防晒霜指数范围,给你每种防晒霜的个数和防晒指数,问最多几头牛能防晒。
网络流解法 : 构图非常简单,源点向每种瓶子连一条瓶子个数的边,瓶子跟能接受的牛连接一条容量为1的边,每头牛向汇点连接一条边容量为1的边,但是这样的话复杂度会比较高,因为点有2500之多。但是比较高效的网络流解法能过。
贪心解法: 先讲牛头按minspf排序,瓶子也排序。然后从防晒指数最小的瓶子开始考虑,能接受他的奶牛当中选择一个maxspf最小的。这样就能得出最优解。
简单证明:
若上述解法没有得出最优解,那么必定存在瓶子i,j。并且i<j。i能满足A牛奶和B奶牛,而j仅能满足A奶牛。并且按前面的操作使得i选择了A奶牛。
按上述操作可以得出 B.maxspf>A.maxspf bottle[j].spf<A.maxspf<B.maxspf bottle[j].spf>bottle[i].spf>B.minspf
那么j能够沐足B奶牛。所以产生了矛盾。
证毕。
下面是贪心解法的代码。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=2500+9;
int n,l;
struct D
{
int low,high;
bool operator < (const struct D &xx) const
{
return(low<xx.low);
}
}d[maxn];
struct B
{
int spf,sum;
bool operator < (const struct B &xx) const
{
return(spf<xx.spf);
}
}bottle[maxn];
struct cmp
{
bool operator() (int a,int b)
{
return(a>b);
}
};
int main()
{
scanf("%d %d",&n,&l);
for(int i=1;i<=n;i++)
scanf("%d %d",&d[i].low,&d[i].high);
sort(d+1,d+n+1);
for(int i=1;i<=l;i++)
scanf("%d %d",&bottle[i].spf,&bottle[i].sum);
sort(bottle+1,bottle+l+1);
int ans=0;
priority_queue <int,vector<int>,cmp> que;
for(int i=1,k=1;i<=l;i++)
{
while(d[k].low<=bottle[i].spf&&k<=n)
{
que.push(d[k].high);
k++;
}
for(int j=1;j<=bottle[i].sum;j++)
{
while(!que.empty()&&que.top()<bottle[i].spf) que.pop();
if(!que.empty())
{
ans++;
que.pop();
}
}
}
printf("%d\n",ans);
return 0;
}