zoukankan      html  css  js  c++  java
  • [优先队列] 洛谷 P1484 种树

    题目描述

    cyrcyr今天在种树,他在一条直线上挖了n个坑。这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树。而且由于cyrcyr的树种不够,他至多会种k棵树。假设cyrcyr有某种神能力,能预知自己在某个坑种树的获利会是多少(可能为负),请你帮助他计算出他的最大获利。

    输入输出格式

    输入格式:

    第一行,两个正整数n,k。

    第二行,n个正整数,第i个数表示在直线上从左往右数第i个坑种树的获利。

    输出格式:

    输出1个数,表示cyrcyr种树的最大获利。

    输入输出样例

    输入样例#1:
    6 3 
    100 1 -1 100 1 -1
    
    输出样例#1:
    200

    说明

    对于20%的数据,n<=20。

    对于50%的数据,n<=6000。

    对于100%的数据,n<=500000,k<=n/2,在一个地方种树获利的绝对值在1000000以内。

    题解

    • 对于一个点,我们可以记录一下它的左边l和它的右边r
    • 若当前i被选了,我们可以把a[i]的值赋值为a[l[i]]+a[r[i]]-a[i](要不一起选要不就一起不选),然后将左边右边的对应该一下就行了

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <queue>
     4 #include <vector>
     5 #define ll long long 
     6 #define N 500010
     7 using namespace std;
     8 struct node 
     9 { 
    10     ll v;int d; 
    11     bool operator <(const node &a)const {return v<a.v;}
    12 }p;
    13 priority_queue<node>Q;
    14 ll a[N],ans;
    15 int l[N],r[N],vis[N],n,k;
    16 int main()
    17 {
    18     scanf("%d%d",&n,&k),r[0]=1,l[n+1]=n;
    19     for (int i=1;i<=n;i++) scanf("%lld",&a[i]),l[i]=i-1,r[i]=i+1,Q.push((node){a[i],i});
    20     while (k--)
    21     {
    22         while (vis[Q.top().d]) Q.pop();
    23         p=Q.top(),Q.pop();
    24         if (p.v<0)  break;
    25         ans+=p.v,a[p.d]=a[l[p.d]]+a[r[p.d]]-a[p.d],p.v=a[p.d],vis[l[p.d]]=vis[r[p.d]]=1,
    26         l[p.d]=l[l[p.d]],r[p.d]=r[r[p.d]],r[l[p.d]]=p.d,l[r[p.d]]=p.d,Q.push((node){p.v,p.d});
    27     }
    28     printf("%lld",ans);
    29 }
  • 相关阅读:
    java扫描文件夹下面的所有文件(递归与非递归实现)
    JAVA8 十大新特性详解
    Intellij IDEA创建的Web项目配置Tomcat并启动Maven项目
    Spring官网下载各版本jar包
    史上最全Java面试题(带全部答案)
    深入JVM对象引用
    23种设计模式全解析
    git difftool和mergetool图形化
    Java技术——你真的了解String类的intern()方法吗
    动手实现一个vue中的模态对话框组件
  • 原文地址:https://www.cnblogs.com/Comfortable/p/10328154.html
Copyright © 2011-2022 走看看