poj 3614 Sunscreen(贪心 优先队列)

每个牛有区间,瓶子的权在这个区间内就可以被该牛用,每种瓶子都有数量限制,且一个瓶子只能被一个牛用,求这些瓶子最多可以被多少牛用

贪心的思路,但是不能确定这个思路对,WA

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
typedef struct
{
    int x;
    int y;
    int w;
} C;
typedef struct
{
    int spf;
    int cvr;
    int wt;
} B;
bool operator >(const C &c1,const C &c2)
{
    if(c1.w>c2.w) return true;
    else if(c1.w==c2.w){
     if(fabs(c1.y-c1.x)>fabs(c2.y-c2.x)) return true;
    }
    return false;
}
bool operator <(const B &c1,const B &c2)
{
    if(c1.wt<c2.wt) return true;
    return false;
}
int main()
{
    int c,l;
    priority_queue<C,vector<C>,greater<C> > pq;
    scanf("%d%d",&c,&l);
    C cow[c];
    B b[l];
    for(int i=0; i<c; i++)
    {
        scanf("%d%d",&cow[i].x,&cow[i].y);
        cow[i].w=0;
    }
    for(int i=0; i<l; i++)
    {
        scanf("%d%d",&b[i].spf,&b[i].cvr);
        b[i].wt=0;
    }
    for(int i=0; i<c; i++)
    {
        for(int j=0; j<l; j++)
        {
            if(cow[i].x<=b[j].spf&&cow[i].y>=b[j].spf)
            {
                cow[i].w++;
                b[j].wt++;
            }
        }
        pq.push(cow[i]);
    }
    sort(b,b+l);
    int sz=l;
    int res=0;
    while(!pq.empty()&&sz)
    {
        C tp=pq.top();
       // printf("%d,%d,%d\n",tp.x,tp.y,tp.w);
        pq.pop();
        for(int j=0; j<l; j++)
        {
            if(!b[j].cvr) continue;
            if(tp.x<=b[j].spf&&tp.y>=b[j].spf)
            {
                b[j].cvr--;
                if(b[j].cvr==0) sz--;
                res++;
            }
        }
    }
    printf("%d\n",res);
    return 0;
}

 

瓶子可以被消耗条件:1.cow.x<=b.spf   2.b.spf<=cow.y

先把牛和瓶子各自安第一个元素排序,对于一个spf值固定的瓶子,它若有多个满足条件的牛时,牛的区间下标越小的越好,因为下标大的还有机会被其它的瓶子收走,也就是下标大的能被收走下标小的瓶子收走,但是下标小的却不一定能被收走下标大的牛的瓶子收走,所以我们总是选最小的那个,就是把它们放在小顶堆里,每次都取最小的那个,我们把瓶子从小到大排序,这样每次遍历一个瓶子时,把所有可以被它收走的牛(满足条件1)都放进堆里,然后把这个瓶子个数消耗完(满足条件2,若是不满足即cow.y<b.spf,则下一个瓶子肯定也不满足,所以不管满不满足都要把这个栈顶的pop掉),若是消耗不完,那它就再也不能被消耗完了,因为堆里的全是满足条件的了,除此之外就没有可以满足它的了,所以就可以看下一个瓶子了i++,若是消耗完了牛还剩下,那这些牛还可以被下一个瓶子消耗,因为下一个瓶子的值更大,所以肯定满足条件,再从堆里取重复上述内容。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
typedef struct
{
    int x;
    int y;
} C;
typedef struct
{
    int spf;
    int cvr;
} B;
bool operator <(const C &c1,const C &c2)
{
    if(c1.x<c2.x) return true;
    else if(c1.x==c2.x)
    {
        if(c1.y<c2.y) return true;
    }
    return false;
}
bool operator <(const B &b1,const B &b2)
{
    if(b1.spf<b2.spf) return true;
    else if(b1.spf==b2.spf)
    {
        if(b1.cvr<b2.cvr) return true;
    }
    return false;
}

bool operator >(const C &c1,const C &c2)
{
    if(c1.y>c2.y) return true;
    return false;
}

int main()
{
    int c,l,i,j;
    priority_queue<C,vector<C>,greater<C> > pq;
    scanf("%d%d",&c,&l);
    C cow[c];
    B b[l];
    for(i=0; i<c; i++)
    {
        scanf("%d%d",&cow[i].x,&cow[i].y);
    }
    for(i=0; i<l; i++)
    {
        scanf("%d%d",&b[i].spf,&b[i].cvr);
    }
    sort(cow,cow+c);
    sort(b,b+l);
    int s=0;
    for(i=0,j=0; i<l; i++)
    {
      while(j<c&&cow[j].x<=b[i].spf){ //把对于b[i],满足条件1的全部放进去
       pq.push(cow[j]);
       j++;
      }
      while(b[i].cvr&&!pq.empty()){ //把b[i]个数耗完
       C cw=pq.top();
       if(cw.y>=b[i].spf){ //满足条件2
        s++;
        b[i].cvr--;
       }
       pq.pop();
      }
    }
    printf("%d\n",s);
}

 

posted @ 2016-03-24 13:15  cherry_yue  阅读(47)  评论(0)    收藏  举报