美文网首页
贪心—Ⅰ

贪心—Ⅰ

作者: Tsukinousag | 来源:发表于2021-02-21 23:23 被阅读0次
    • 防晒

    原题链接

    我们首先将奶牛可以承受的最小值,递减排序,也就是降序排列,然后将防晒霜固定的值,递减排序,还是降序排列.

    对于每头奶牛,扫描一遍所有防晒霜,在这头奶牛能用的防晒霜里找SPF最大的使用

    注意:降序排序,保证对于每一头牛而言,它用的是,可以使用的最差的防晒霜,因为值越小的防晒霜,有可能让更多的牛使用.而升序排列,就恰好反了.

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    
    using namespace std;
    
    const int N=3500;
    int n,m;
    
    struct node
    {
        int spf,cover;
    }a[N];
    
    struct node2
    {
        int min_spf,max_spf;
    }b[N];
    
    bool cmp1(node2 a,node2 b)
    {
            return a.min_spf>b.min_spf;
    }
    
    bool cmp2(node a,node b)
    {
            return a.spf>b.spf;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%d%d",&b[i].min_spf,&b[i].max_spf);
        sort(b,b+n,cmp1);
        for(int i=0;i<m;i++)
            scanf("%d%d",&a[i].spf,&a[i].cover);
        sort(a,a+m,cmp2);
        
        int ans=0;
        for(int i=0;i<n;i++)//枚举奶牛
        {
            for(int j=0;j<m;j++)//枚举防晒霜
            {
                if(a[j].spf>=b[i].min_spf&&a[j].spf<=b[i].max_spf&&a[j].cover)
                {
                    ans++;
                    a[j].cover--;
                    break;//枚举下一头奶牛
                }
            }
        }
        printf("%d\n",ans);
        return 0;
    }
    
    • 畜栏预定

    原题链接

    贪心+小根堆

    维护一个小根堆,记录当前每个畜栏安排进去的最后一头牛
    依次对于每头牛,与小根堆堆顶比较,若不小于畜栏最后一头牛结束吃草的时间,则加入,如果这样的畜栏不存在,则为其新建一个畜栏

    时间复杂度为:O(NlogN)

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    typedef pair<int,int>PII;
    
    const int N=50010;
    
    int n;
    
    int id[N];//牛对应其牛栏号
    pair<PII,int>cow[N];
    
    
    
    int main()
    {
        cin>>n;
        for(int i=0;i<n;i++)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            cow[i]={{l,r},i};//第i号牛的进与出
        }
        
        sort(cow,cow+n);//按照左端点排序,一个一个加
        
        priority_queue<PII,vector<PII>,greater<PII> >heap;
        int num=1;
        
        heap.push({cow[0].first.second,num});//0号牛最晚结束时间,即其牛栏号
        
        id[cow[0].second]=1;//0号牛对应栅栏1号
        
        //往里面放牛
        for(int i=1;i<n;i++)
        {
             int l=cow[i].first.first,r=cow[i].first.second,cowid=cow[i].second;
             
             if(l>heap.top().first)//若这只牛能放进这里面
             {
                 int t=heap.top().second;//记录一下牛栏号
                 heap.pop();//此牛栏更新最晚结束时间
                 heap.push({r,t});
                 id[cowid]=t;
             }
             else//新建牛栏
             {
                 heap.push({r,++num});
                 id[cowid]=num;
             }
        }
        cout<<heap.size()<<endl;
        for(int i=0;i<n;i++)
            cout<<id[i]<<endl;
        
        return 0;
    }
    
    
    • 雷达设备

    原题链接

    由勾股定理可知,将所有小岛转化成区间后,问题转化为:给定 n 个区间,在 x 轴上选择尽量少的点,使得所有区间至少包含一个点。

    算法步骤:

    将所有区间按右端点从小到大排序;

    依次考虑每个区间:如果当前区间包含最后一个选择的点,则直接跳过;如果当前区间不包含最后一个选择的点,则在当前区间的右端点的位置选一个新的点;

    时间复杂度:

    计算每个坐标所对应的区间,需要 O(n) 的计算量;
    将所有区间排序需要 O(nlogn) 的计算量;
    扫描所有区间需要 O(n) 的计算量;
    所以总共的时间复杂度是 O(nlogn)。

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    
    using namespace std;
    
    const int N=1005;
    
    typedef pair<double,double>PDD;
    
    double INF=0x3f3f3f3f;
    int n,r;
    
    PDD seg[N];
    
    int main()
    {
        cin>>n>>r;
        
        bool success=true;
        
        for(int i=0;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            if(y>r)
            {
                success=false;
                break;
            }
            auto len=sqrt(r*r-y*y);
            seg[i]={x+len,x-len};
        }
        if(!success)
        {
            printf("-1\n");
        }
        else
        {
            sort(seg,seg+n);//按照尾边排序
            int res=0;//统计雷达数
            double last=-INF;
            for(int i=0;i<n;i++)
            {
                if(seg[i].second>last)
                {
                    res++;
                    last=seg[i].first;
                }
            }
            cout<<res;
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:贪心—Ⅰ

          本文链接:https://www.haomeiwen.com/subject/tuicfltx.html