poj3614 Sunscreen(贪心)

题意

有C个奶牛去晒太阳,每个奶牛各自能够忍受的阳光强度有一个最小值mn和一个最大值mx,太大就晒伤了,太小奶牛没感觉。
而刚开始的阳光的强度非常大,奶牛都承受不住,然后奶牛就得涂抹防晒霜,防晒霜的作用是让阳光照在身上的阳光强度固定为某个值。
那么为了不让奶牛烫伤,又不会没有效果。
给出了L种防晒霜。每种的固定的阳光强度a和数量n也给出来了。
每个奶牛只能抹一瓶防晒霜,最后问能够享受晒太阳的奶牛有几个。

题解1

匈牙利算法
这是一道裸的二分图匹配,防晒霜配奶牛,连边做匈牙利就好了。

题解2

贪心

奶牛按mx从小到大排,相同则按mn从小到大排。
防晒霜按a从小到大排。
对于每头奶牛选择范围内最小的防晒霜。

为什么要选择范围内最小的呢?
有一种证明是这样的,假设现在有两瓶防晒霜x,y,SFA分别是SFA[x],SFA[y],SFA[x]<SFA[y],因为mx是递增的,那么后面会有3种情况:x、y都能用;x、y都不能用;y能用,x不能用。可以看出y的潜能更大一点,所以保留SFA较大的y,选择SFA较小的x。

同理如果把mn从大到小排,则选择范围内最大的。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxl=2510;

struct cow
{
    int mn,mx;
    bool operator<(cow c1)
    {
        if(mx!=c1.mx) return mx<c1.mx;
        return mn<c1.mn;
    }
}a[maxl];
struct fss
{
    int a,n;
    bool operator<(fss f1)
    {
        return a<f1.a;
    }
}b[maxl];

bool cmp_a(cow c1,cow c2)
{
    return c1<c2;
}
bool cmp_b(fss f1,fss f2)
{
    return f1<f2;
}

int main()
{
    int c,l;
    scanf("%d%d",&c,&l);
    for(int i=1;i<=c;i++) scanf("%d%d",&a[i].mn,&a[i].mx);
    for(int i=1;i<=l;i++) scanf("%d%d",&b[i].a,&b[i].n);
    sort(a+1,a+c+1,cmp_a);
    sort(b+1,b+l+1,cmp_b);
    int ans=0,p=1;
    for(int i=1;i<=c;i++)
    {
        for(int j=1;j<=l;j++)
        {
            if(b[j].n>0 && a[i].mn<=b[j].a && b[j].a<=a[i].mx )
            {
                ans++;
                b[j].n--;
                break;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a_bright_ch/article/details/81082132