此题大意:
有一些奶牛,它们想晒黑皮肤,每只奶牛有一个min_SPA 和 max_SPA,如果高于max_SPA,就不能晒黑,低于的话就会晒伤,而题上又给了几瓶防晒霜,能够使奶牛达到一定SPA,并且一瓶可以几头奶牛一起用,让你求最大的晒黑的奶牛头数。
开始我是这样理解的:
先对奶牛的SPA进行排降序,以max为主,min为辅;
然后对防晒霜排降序,以SPA的值为主,防晒头数为辅;
然后循环找防晒霜覆盖的范围;
但事实上我漏了一点就是下面这种情况:
3 2
1 6
3 4
3 4
3 1
2 1
从图上可以看出,如果找的第一个是最大的1 6,那么接下来就找不到其它的了,事实上却是可以的
因此,我改进了一下:
在找的时候运用了堆维护找到的大于防晒霜SPA的max的min,换句话说就是维护min_SPA;
于是就解决了这个问题。
代码如下:
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#define maxn 3000
using namespace std;
struct node
{
int x,y;
};
node C[maxn], L[maxn];
bool cmp1(node num1, node num2)
{
if (num1.y == num2.y) return num1.x > num2.x;
else return num1.y > num2.y;
}
bool cmp2(node num1, node num2)
{
if (num1.x == num2.x) return num1.y > num2.y;
else return num1.x > num2.x;
}
int main()
{
priority_queue<int, vector<int> > que; // 大顶堆
int c, l;
scanf("%d%d", &c, &l);
for (int i = 0; i < c; ++i)
scanf("%d%d", &C[i].x, &C[i].y); //以y为主,x为辅排序
for (int i = 0; i < l; ++i)
scanf("%d%d", &L[i].x, &L[i].y); //以x为主,y为辅排序
sort(C, C + c, cmp1);
sort(L, L + l, cmp2);
int ans = 0, j = 0;
for (int i = 0; i < l; ++i)
{
while (j < c && C[j].y >= L[i].x) //将大于乳液的光照强度的奶牛的min_FPA放进堆里维护
{
que.push(C[j].x);
++j;
}
while (!que.empty() && L[i].y) //将维护的数据从小开始取
{
int num = que.top();
que.pop();
if (L[i].x < num) continue; //若大于了乳液的光照强度,则不能使用
++ans;
--L[i].y;
}
}
printf("%d\n", ans);
return 0;
}