AcWing 110 防晒

题解:
emmm这个题目是一个贪心的问题,但是一开始理的不是很清楚…
首先这个题目提供两种方法,一种是一般贪心,还有一种就是使用了一下优先队列,其实原理都是一样的。
法一:
我们把奶牛的minSPF从大到小排序,然后再对防晒霜按照SPF降序排序,这样我们对于每个奶牛都去选择SPF最大的那个防晒霜。可以证明的是:对于前面的奶牛,如果这个防晒霜的SPF大于minSPF,那么之后的奶牛一定也满足这个条件。也就是说,当前奶牛可用的任意两瓶防晒霜x,y,如果SPF(x) > SPF(y),那么对后面的奶牛就一定会存在这三种情况:1)x,y都可以用。2)x,y都不能用,3)x不能用但是y可以用。所以相比较而言,选择SPF值更大的那一方肯定是更优的决策。
法二:
我们先对奶牛的minSPF值从小到大排序,再对防晒霜的SPF值从小到大排序,我们先判断当前minSPF是否小于SPF,如果满足就把他对应的最大值放进优先队列里,直到放不进去,然后对优先队列中的值进行比较,如果maxSPF大于SPF答案累计加一。
这里注意,我们并没有对队列进行清空,是因为之后的maxSPF也会有满足的情况,又因为我们之前已经对minSPF排过序,所以后入队的奶牛的minSPF也一定大于上一个SPF的值。
AC代码(法一):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn = 3000;

struct Cow
{
    int maxs,mins;
}cow[maxn];

struct SPF
{
    int cover,sp;
}s[maxn];

bool cmd(Cow a,Cow b)
{
    if(a.mins != b.maxs) return a.mins > b.mins;
    else return a.maxs > b.maxs;
}

bool cmp(SPF a,SPF b)
{
    if(a.sp != b.sp) return a.sp > b.sp;
    else return a.cover > b.cover;
}

int main()
{
    int c,l,ans = 0;
    cin >> c >> l;
    for(int i = 1;i <= c;i++) cin >> cow[i].mins >> cow[i].maxs;
    for(int i = 1;i <= l;i++) cin >> s[i].sp >> s[i].cover;
    sort(cow + 1,cow + 1 + c,cmd);
    sort(s + 1,s + 1 + l,cmp);
    for(int i = 1;i <= c;i++){
        for(int j = 1;j <= l;j++){
            if(cow[i].mins <= s[j].sp && cow[i].maxs >= s[j].sp && s[j].cover != 0){
                ans++;
                s[j].cover--;
                break;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

AC代码(法二):

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;

const int maxn = 3000;

struct Cow
{
    int min_spf,max_spf;
}cow[maxn];

struct SPF
{
    int sp,cover;
}s[maxn];

bool cmd(Cow a,Cow b)
{
    if(a.min_spf != b.min_spf) return a.min_spf < b.min_spf;
    else a.max_spf > b.max_spf;
}

bool cmp(SPF a,SPF b)
{
    if(a.sp != b.sp) return a.sp < b.sp;
    else return a.cover > b.cover;
}

int main()
{
    int c,l;
    cin >> c >> l;
    for(int i = 1;i <= c;i++) cin >> cow[i].min_spf >> cow[i].max_spf;
    for(int i = 1;i <= l;i++) cin >> s[i].sp >> s[i].cover;
    sort(cow + 1,cow + 1 + c,cmd);
    sort(s + 1,s + 1 + l,cmp);
    priority_queue<int,vector<int>,greater<int> > q;
    int k = 1,ans = 0;
    for(int i = 1;i <= l;i++){
        while(k <= c && cow[k].min_spf <= s[i].sp){
            q.push(cow[k++].max_spf);
        }
        while(!q.empty() && s[i].cover != 0){
            int a = q.top();
            q.pop();
            if(a < s[i].sp) continue;
            ans++;
            s[i].cover--;
        }
    }
    cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CUCKyrie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值