zoukankan      html  css  js  c++  java
  • bzoj2151: 种树

    思路很妙啊。

    我一开始就在想DP,但是时间必挂。

    膜了题解才发现原来是贪心。首先如果没有限制左右不能选,那就很简单,那现在的做法就是给他一个反悔的机会

    比如数列9 10 8 -1

    那贪心一开始就选10,这时把数列变成:9+8-10 -1 = 7 -1

    那么下一次选的就是7,相当于减的10抵消而选了9、8

    那么用链表维护左右,用优先队列排序就行了。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    struct node
    {
        int id,d;
    }a[210000];
    struct cmd
    {
        bool operator()(node n1,node n2)
        {
            return (n1.d==n2.d)?(n1.id<n2.id):(n1.d<n2.d);
        }
    };
    priority_queue<node,vector<node>,cmd>q,d;
    int c[210000],l[210000],r[210000];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        if(n/2<m){printf("Error!
    ");return 0;}
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&c[i]);
            a[i].id=i;a[i].d=c[i];q.push(a[i]);
            l[i]=i-1;if(l[i]==0)l[i]=n;
            r[i]=i+1;if(r[i]==n+1)r[i]=1;
        }
        
        int ans=0;
        for(int i=1;i<=m;i++)
        {
            node n1,n2;
            while(1)
            {
                n1=q.top();
                if(d.empty()==true){q.pop();break;}
                n2=d.top();
                if(n1.d==n2.d&&n1.id==n2.id)
                {
                    q.pop();n1=q.top();
                    if(d.empty()==true)break;
                    d.pop();n2=d.top();
                }
                else {q.pop();break;}
            }
            
            ans+=n1.d;
            int L=l[n1.id],R=r[n1.id];
            
            node de;
            de.id=L,de.d=c[L];d.push(de);
            de.id=R,de.d=c[R];d.push(de);
            
            node in;
            in.id=n1.id,in.d=c[L]+c[R]-n1.d;q.push(in);
            
            c[n1.id]=c[L]+c[R]-n1.d;
            l[n1.id]=l[L];r[l[L]]=n1.id;
            r[n1.id]=r[R];l[r[R]]=n1.id;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    网游内存数据库的设计(1)
    基于用户级线程的远程调用效率测试
    实现c协程
    KendyNet for linux
    开源一个lua的网络库
    C语言重写网络发送/接收封包
    C协程使用举例
    各种内存分配器的对比测试
    KendyNet性能测试
    C协程实现的效率对比
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8643000.html
Copyright © 2011-2022 走看看