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 }
  • 相关阅读:
    Restful api 返回值重复的问题
    fastDFS遇到的并发问题recv cmd: 0 is not correct, expect cmd: 100
    忽略警告@SuppressWarnings的用法
    Mysql 一些命令记录
    python 操作excel实现替换特定内容
    python 提取目录中特定类型的文件
    python使用tkinter无法获取输入框的值
    python使用tkinter无法给顶层窗体的输入框设定默认值
    游戏基础知识第一弹
    python 3.7.4 安装 opencv
  • 原文地址:https://www.cnblogs.com/Comfortable/p/10328154.html
Copyright © 2011-2022 走看看