AcWing 110 防晒
题目描述:
有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
输入样例:
[code]3 2 3 10 2 5 1 5 6 2 4 1
输出样例:
[code]2
分析:
本题是经典区间贪心的一类变形。在区间问题中,我们一般按照结束时间进行排序,优先选择最晚结束时间的区间;或者按照开始时间从大到小排序,优先选择最晚开始时间。本题需要相当细心,很容易出错。
第一个需要注意的是一般区间问题选择了这个区间,便可以继续考察下一个区间了,具有单调性。而本题不具有该性质,用双指针的话会出错。下面先介绍两种思路。
方法一:按照奶牛的最大spf排序,然后从符合条件的防晒霜中选择最小spf的一个。
格外需要注意的是,这里的区间是奶牛的spf,点是防晒霜的spf,我们在给第一头奶牛选择出了适合它的防晒霜后,适合第二头的防晒霜的spf可能比之前选出的大,也可能比之前的小,因为符合他们要求的防晒霜并不是相同的集合。
实现方式很灵活,贪心的一般思路需要排序,按照奶牛最大的spf排序,不需要写个cmp。完全可以利用sort给结构体排序时默认按照第一个成员大小进行排序的性质,将maxspf作为奶牛spf二元组的第一个变量即可。之后再对防晒霜进行排序。
最后为每头奶牛依次枚举符合条件的防晒霜,最小符合条件的即是spf最小的防晒霜。
[code]#include <iostream> #include <algorithm> using namespace std; pair<int,int> a[2550],b[2550]; int main(){ int c,l,ans = 0; cin>>c>>l; for(int i = 0;i < c;i++) cin>>a[i].second>>a[i].first; for(int i = 0;i < l;i++) cin>>b[i].first>>b[i].second; sort(a,a + c); sort(b,b + l); for(int i = 0;i < c;i++){ for(int j = 0;j < l;j++){ if(b[j].second && a[i].second <= b[j].first && a[i].first >= b[j].first){ ans++; b[j].second--; break; } } } cout<<ans<<endl; return 0; }
方法二:按照奶牛的最小spf从大到小排序,然后从符合条件的防晒霜中选择最大spf的一个。
按照奶牛的最小spf从大到小排序,同样不用刻意写cmp(能偷懒绝不多写几行)。我们按照minspf从小到大排序,之后倒着枚举即可。防晒霜也是一样,排序后倒着枚举最先找到的即是spf最大的一个。
[code]#include <iostream> #include <algorithm> using namespace std; pair<int,int> a[2550],b[2550]; int main(){ int c,l,ans = 0; cin>>c>>l; for(int i = 0;i < c;i++) cin>>a[i].first>>a[i].second; for(int i = 0;i < l;i++) cin>>b[i].first>>b[i].second; sort(a,a + c); sort(b,b + l); for(int i = c - 1;i >= 0;i--){ for(int j = l - 1;j >= 0;j--){ if(b[j].second && a[i].first <= b[j].first && a[i].second >= b[j].first){ ans++; b[j].second--; break; } } } cout<<ans<<endl; return 0; }
最后简单分析下这两种思路成立的原因。 按照奶牛的最大spf排序,在符合条件的防晒霜中优先选取最小spf的那个。比如x和y都符合奶牛的条件,spf值x < y,若x被选取,则y也可能符合下一头奶牛(最大spf更大)的要求;反之若选择了y,很可能x就不再符合下一头奶牛的要求了。或者说,对于当前奶牛,x和y均可用,而对于下一头奶牛,若x可用,则给当前奶牛还是下一头均对答案贡献一样,都是一头,若y可用,下一头牛就可以使用y了。会不会存在对于当前奶牛x,y均可用,而下一头牛x可用,y不可用的情况呢?不会的,因为当前奶牛的区间包含了x,y,若下一头牛包含x,且区间右端点大于当前牛,那么必然也包含y。(画个图就显而易见了)。第二种思路的原理也是一样。可能表达得不够清楚,但是区间贪心十有八九都是这两种策略是正确的,即使不知道原理,也是可以使用的。
- AcWing 111 畜栏预定
- AcWing 114 国王游戏
- bzoj1012(B站AC第六题)
- AC dreamoj 1011 树状数组+hash维护字符串的前缀和
- configure.ac和makefile.am
- 【贪心】今年暑假不AC
- HDU 5164Matching on Array(AC自动机)
- Uva-815 - Flooded!-AC
- 1-9加减得到110 匪警请拨110,即使手机欠费也可拨通!
- [Leetcode 110, Easy] Balanced Binary Tree
- PAT A1012 The Best Rank 极度依靠书的思路再自己做的。。。不过ac一次过了
- 项目经验:GIS<MapWinGIS>建模第四天
- bzoj 3435: [Wc2014]紫荆花之恋 替罪羊树维护点分治 && AC400
- hdu 3065 病毒侵袭持续中(ac自动机模板题)
- ACM--steps--dyx--1.3.2--今年暑假不AC
- 杭电 acm 今年暑假不AC
- 第几天 AC 杭电
- 邮件服务端口 port 25、109、110、143、465、995、993
- RQNOJ57 AC之后~~
- HDU 2222 Keywords Search(AC自动机)