题目描述
有C头奶牛进行日光浴,第i头奶牛需要minSPF[i]到maxSPF[i]单位强度之间的阳光。
每头奶牛在日光浴前必须涂防晒霜,防晒霜有L种,涂上第i种之后,身体接收到的阳光强度就会稳定为SPF[i],第i种防晒霜有cover[i]瓶。
求最多可以满足多少头奶牛进行日光浴。
输入格式
第一行输入整数C和L。
接下来的C行,按次序每行输入一头牛的minSPF和maxSPF值,即第i行输入minSPF[i]和maxSPF[i]。
再接下来的L行,按次序每行输入一种防晒霜的SPF和cover值,即第i行输入SPF[i]和cover[i]。
每行的数据之间用空格隔开。
输出格式
输出一个整数,代表最多可以满足奶牛日光浴的奶牛数目。
数据范围
$1≤C,L≤2500$
$1≤minSPF≤maxSPF≤1000$
$1≤SPF≤1000$
样例
输入样例:
3 2
3 10
2 5
1 5
6 2
4 1
输出样例:
2
贪心+排序
我们首先将奶牛可以承受的最小值,递减排序,也就是降序排列,然后将防晒霜固定的值,递减排序,还是降序排列.
对于每一个头奶牛而言,当然是要选择目前来说满足条件的最差的防晒霜,什么最差的定义,就是选择满足奶牛条件的SPF最大的那一瓶防晒霜.
注意:降序排序,保证对于每一头牛而言,它用的是,可以使用的最差的防晒霜,因为值越小的防晒霜,有可能让更多的牛使用.而升序排列,就恰好反了.
C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N=3500;
int n,m,i,j,k;
struct node
{
int spf,cover;
} a[N];
struct node2
{
int min_spf,max_spf;
} b[N];
int cmp(node a,node b)
{
if (a.spf==b.spf)
return a.cover>b.cover;
return a.spf>b.spf;
}
int cmp2(node2 a,node2 b)
{
if (a.min_spf==b.min_spf)
return a.max_spf>b.max_spf;
return a.min_spf>b.min_spf;
}
int main()
{
cin>>n>>m;
for (i=1;i<=n;i++)
cin>>b[i].min_spf>>b[i].max_spf;
sort(b+1,b+1+n,cmp2);
for (i=1;i<=m;i++)
cin>>a[i].spf>>a[i].cover;
sort(a+1,a+1+m,cmp);
int ans=0;
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
if (a[j].spf<=b[i].max_spf && a[j].spf>=b[i].min_spf && a[j].cover)
{
a[j].cover--;
ans++;
break;
}
}
cout<<ans;
return 0;
}
LYD老师的代码
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN 20000
int n,m,ans;
pair<int,int> cow[MAXN],lotion[MAXN];
priority_queue<int> q;
void process(){
int i,i1;
while(!q.empty()) q.pop();
sort(cow,cow+n);
sort(lotion,lotion+m);
for(ans=i=i1=0;i<m;i++){
while((i1<n)&&(cow[i1].first<=lotion[i].first))
q.push(-cow[i1++].second);
while((!q.empty())&&(-(q.top())<lotion[i].first))
q.pop();
while((!q.empty())&&(lotion[i].second--)){
ans++;
q.pop();
}
}
}
int main(){
int i,j;
freopen("tanning.in","r",stdin);
freopen("tanning.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d%d",&cow[i].first,&cow[i].second);
for(i=0;i<m;i++)
scanf("%d%d",&lotion[i].first,&lotion[i].second);
ans=0;
process();
printf("%d\n",ans);
return 0;
}
试了一下升序,maxspf递增,minspf越小越前,spf也递增
(自己总结来说就是整个区间越偏小用的spf要越小,整个区间偏大的spf用大的,这样中间的spf就能充分利用)
int cmp(node a,node b)
{
if (a.spf==b.spf)
return a.cover>b.cover;
return a.spf<b.spf;
}
int cmp2(node2 a,node2 b)
{
if (a.max_spf==b.max_spf)
return a.min_spf<b.min_spf;
return a.max_spf<b.max_spf;
}
最小的给最少的用,最大的给最大的用,这不是并不矛盾吗?为什么不行呢?
为什么不能将奶牛的单位强度按照minSPF从小到大排序,然后防晒霜也按照从小到大排序,将最小的先和最小的进行排序呢?
因为降序排的时候,对于SPF[J] > SPF[I],对后续奶牛SPF[J]能用的时候SPF[I]一定能用。而升序排的时候,对于SPF[I] < SPF[J],对于后续奶牛SPF[I]能用的时候SPF[J]不一定能用,也就是用掉了后面奶牛的防晒霜。比如(1,5),(2,3)和1,2防晒霜。
明白了,谢谢大佬
笔误了,是(1,5)和(2,3)和2,5防晒霜
所选择的排列和决策方式,一定也要满足原解的贪心条件,也就是当前所选防晒霜如果能被后续奶牛选,其他防晒霜也必须得能被后续奶牛选,否则会出现选掉后续奶牛特有防晒霜的情况。而当前防晒霜不能被后续奶牛选的时候,选当前防晒霜没问题。
升序排列的话只能按maxSPF升序排并且选择最小SPF防晒霜才能满足这样的贪心条件。
升序排列有问题,但降序排没错,玄学
要记得都反过来哦.
反过来好像不行,不知道哪有问题
我知道我错哪了,感谢大佬
大佬加油!
不懂为什么要降序排,我升序排就是错的。。
二者区别在哪?
降序排序,保证对于每一头牛而言,它用的是,可以使用的最差的防晒霜,因为值越小的防晒霜,有可能让更多的牛使用.而升序排列,就恰好反了.
我懂了,升序要按最大值排,感谢。
不谢啦.= ̄ω ̄=
为什么升序要最大值
降序要最小值,升序自然就是最大值.
[L,R]区间,降序要的是R越大,L越小.
同样的,降序要的是L越小,R越大.
可以这样理解吗 升序只看R 降序只看L
没有问题.