• bzoj4977 跳伞求生——贪心


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4977

    今天讲的贪心题,真神奇啊;

    首先,要得到尽量多选队友的解;

    把队友按 a[i] 从小到大排序,敌人按 b[i] 从小到大排序,然后对于每个队友,选择能攻击的、收益最多的敌人;

    如果没有能攻击的敌人,就把之前最小的一个队友踢掉代替,能使答案更优;

    但尽量多选队友不一定是最终的最优答案,因为有些价值很小(为负)的敌人不如不选;

    所以需要调整,很妙的做法,就是直接踢掉最小的队友和收益最小的敌人,那么剩下的队友和敌人也一定可以配对,过程中取最优解;

    于是去写了,然而秒WA,自己码力好弱啊,打击...

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    int const maxn=1e5+5,inf=1e9;
    int n,m,a[maxn];
    ll ans;
    bool vis[maxn],out[maxn];
    struct N{
        int b,c,bh;
        bool operator < (const N &y) const
        {
            return c-b<y.c-y.b;//priority_queue大根堆 
        }
    }p[maxn],t[maxn];
    priority_queue<N>qen;
    priority_queue<int>q2;
    priority_queue<int>q;
    bool cmp(N x,N y){return x.b<y.b;}
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=m;i++)scanf("%d%d",&p[i].b,&p[i].c);
        sort(a+1,a+n+1); sort(p+1,p+m+1,cmp);
        for(int i=1;i<=m;i++)p[i].bh=i;
        int j=1,pr=1;
        for(int i=1;i<=n;i++)
        {
            while(p[j].b<=a[i]) {qen.push(p[j]); j++;}
            if(!qen.size()) {t[i]=t[pr]; out[pr]=1; pr++;}
            else {t[i]=qen.top(); vis[t[i].bh]=1; qen.pop();}
        }
        for(int i=1;i<=n;i++)
            if(!out[i])ans+=a[i]-t[i].b+t[i].c;
        for(int i=1;i<=m;i++) if(vis[i])q2.push(p[i].b-p[i].c);
        for(int i=1;i<=n;i++) if(!out[i])q.push(-a[i]);//
        ll tmp=ans;
        while(q.size()&&q2.size())
        {
            int x=-q.top(); q.pop();
            int y=-q2.top(); q2.pop();
            tmp-=x; tmp-=y;
            ans=max(ans,tmp);
        }
        printf("%lld
    ",ans);
        return 0;
    }

    看看人家写的简洁优美AC代码:https://blog.csdn.net/dream_lolita/article/details/79302382

    然后就模仿着写了;练习码力...

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    int const maxn=1e5+5;
    int n,m,w[maxn],hd,tl;
    ll ans,sum;
    struct N{
        int x,y; bool tp;
        bool operator < (const N &b) const
        {
            if(x==b.x)return tp<b.tp;
            else return x<b.x;
        }
        N(int x=0,int y=0,bool t=0):x(x),y(y),tp(t) {}
    }t[maxn<<1];
    priority_queue<int>q;
    priority_queue<int,vector<int>,greater<int> >p;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x;i<=n;i++)scanf("%d",&t[i].x);
        for(int i=1,x,y;i<=m;i++)
        {
            n++;
            scanf("%d%d",&x,&y);
            t[n]=N(x,y-x,1);
        }
        sort(t+1,t+n+1);
        hd=1;
        for(int i=1;i<=n;i++)
        {
            if(t[i].tp)q.push(t[i].y);
            else
            {
                if(!q.size())
                {
                    if(hd<=tl)
                    {
                        int tmp=w[hd]; hd++;
                        sum+=t[i].x-tmp;
                        w[++tl]=t[i].x;
                    }
                }
                else
                {
                    int tmp=q.top(); q.pop();
                    sum+=t[i].x+tmp;
                    p.push(tmp);//tmp被使用过 
                    w[++tl]=t[i].x;
                }
            }
        }
        ans=sum;
        for(int i=hd;i<=tl;i++)
        {
            sum-=w[i]+p.top(); p.pop();
            ans=max(ans,sum);
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    POJ 2342
    SHU 413
    SHU 414
    进制转换模板
    SHU 第15届上海大学程序设计联赛夏季赛[热身赛] 第三题(G题)
    POJ 3185
    XTU 1260
    高斯消元法模板
    POJ 2057
    模态窗口的定时关闭
  • 原文地址:https://www.cnblogs.com/Zinn/p/9319745.html
Copyright © 2020-2023  润新知