zoukankan      html  css  js  c++  java
  • bzoj 2151 种树——贪心+后悔

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

    似乎是半年+前讲过的。(然而看到的时候却不会了)

    考虑贪心,限制就是不能选两边的。如果选了最大的又要反悔,一定不可能是要只选旁边的一个,而是把两个都选了;

    所以选了这个以后,把两边的打上标记表示不能选,往堆里加入一个值为 两边的值-自己的值 的元素表示反悔选择即可。

    维护两边是谁,自己用了链表。也许这就是自己很慢的原因?

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=2e5+5;
    int n,m,a[N<<1],tot,ans,pr[N<<1],nt[N<<1];
    bool vis[N<<1];
    struct cmp{
      bool operator() (int u,int v)
      {
        return a[u]<a[v];
      }
    };
    priority_queue<int,vector<int>,cmp> q;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    int main()
    {
      n=rdn(); m=rdn(); tot=n;
      for(int i=1;i<=n;i++)
        {
          a[i]=rdn();q.push(i);
          pr[i]=i-1;nt[i]=i+1;
        }
      if(m>(n>>1)){puts("Error!");return 0;}
      pr[1]=n; nt[n]=1;
      for(int i=1,x,y,k;i<=m;i++)
        {
          k=q.top(); q.pop();
          while(vis[k])k=q.top(),q.pop();
          ans+=a[k]; x=pr[k]; y=nt[k];
          a[++tot]=a[x]+a[y]-a[k]; q.push(tot);
          vis[x]=1; vis[y]=1;
          nt[pr[x]]=tot; pr[tot]=pr[x];
          pr[nt[y]]=tot; nt[tot]=nt[y];
        }
      printf("%d
    ",ans);
      return 0;
    }
  • 相关阅读:
    MySql
    027 mysql
    navicat
    基于阿里云资源的分布式部署方案
    translate(50%,50%) 实现水平垂直居中
    SSH2 协议详解
    DNS服务配置篇 巴哥学Server2003
    Java 8 后的新功能梳理
    IBM Cognos BI 最佳实践系列 网站地址
    jsf2.0 入门视频 教程
  • 原文地址:https://www.cnblogs.com/Narh/p/9817886.html
Copyright © 2011-2022 走看看