P2887 [USACO07NOV]防晒霜Sunscreen - 贪心

貌似这种区间贪心题多数是排序加堆来做。。。

使尽量多的奶牛被抹,需要用最贴近他下限的防晒霜去抹,考虑完他的下限是否可行之后,还要考虑那些使用相同防晒霜的奶牛,应该优先分配给上限最低的
奶牛按下限,防晒霜按低排序后,对于每一款防晒霜,把下限符合奶牛的都放到堆里,找出上限最低的,抹上就好了

这道题我一开始没贪全,因为只考虑了左端点,连右端点是否可行都没考虑。。。而考虑到了右端点可行后又没考虑多个区间叠在一起的情况。。。

注意,使用队列栈堆这些数据结构时要多加!q.empty(),每次取这些数据结构的值(执行q.top()什么的)之前要先判断是否为空,循环的时候也要把empty作为循环条件,总之各种判断条件顺便带上一个!q.empty()
静态差错的时候注意,如果有些地方队列为空是否会被卡掉,然后加empty就好了

#include 
#include 
#include 
#include 
#include 
using namespace std;
#define debug(x) cerr << #x << "=" << x << endl;

const int MAXN = 3000 + 10;
int n,c,ans,tot,lll,vis[MAXN];

struct cows{
    int l, r, id;
    bool operator < (const cows &a) const {
        return r > a.r;
    }
}cow[MAXN];

priority_queue q;

struct picnic{
    int cnt, spfx;
}pic[MAXN];

bool cmpc(cows a, cows b) {
    return a.l < b.l;
}

bool cmpp(picnic a, picnic b) {
    return a.spfx < b.spfx;
}

int main() {
    scanf("%d%d", &c, &lll);
    for(int i=1; i<=c; i++) {
        scanf("%d%d", &cow[i].l, &cow[i].r);
        cow[i].id = i;
    }
    sort(cow+1, cow+c+1, cmpc);
    for(int i=1; i<=lll; i++) {
        scanf("%d%d", &pic[i].spfx, &pic[i].cnt);
    }
    sort(pic+1, pic+lll+1, cmpp);
    tot = 1;
    for(int i=1; i<=lll; i++) {
        while(!q.empty()) q.pop();
        int spfx = pic[i].spfx;
        int cnt = pic[i].cnt;
        for(int j=1; j<=c; j++) {
            if(cow[j].l <= spfx && !vis[cow[j].id]){
                q.push(cow[j]);
            } 
        }
        if(q.empty()) continue;
        cows temp = q.top();
        while(!q.empty()) {
            temp = q.top();
            q.pop();
            if(temp.r >= spfx) {
                cnt--;
                ans++;
                vis[temp.id] = 1; 
            }
            if(cnt == 0) break;
        }
    }
    printf("%d", ans);
    return 0;
}

你可能感兴趣的:(NOIP,贪心,数据结构)