Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)

题意:

你是一名建筑工程师,现给出 n 幢建筑的预计建设高度,你想建成峰状,如:

1 2 3 2 1 → 1 2 3 2 1

1 2 3 1 2 → 1 2 3 1 1

8 10 6 → 8 10 6

10 6 8 → 10 6 6

问所有建筑的高度和最大为多少。

思路:

单调递增栈栈顶存储以当前点为峰的单侧最低高度下标,另存储以每个点为峰的左右最大高度和。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll; const int M = 550000; ll a[M], l[M], r[M]; int main()
{
int n; cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i]; stack<int> st; for (int i = 1; i <= n; i++)//递推每个点左侧的最大高度和
{
while (!st.empty() && a[st.top()] >= a[i]) st.pop();
if (st.empty()) l[i] = i * a[i];
else l[i] = l[st.top()] + (i - st.top()) * a[i];
st.push(i);
} while (!st.empty()) st.pop(); for (int i = n; i >= 1; i--)//递推每个点右侧的最大高度和
{
while (!st.empty() && a[st.top()] >= a[i]) st.pop();
if (st.empty()) r[i] = (n - i + 1) * a[i];
else r[i] = r[st.top()] + (st.top() - i) * a[i];
st.push(i);
} ll res = 0, id = 0;
for (int i = 1; i <= n; i++)//寻找最大高度和的峰点
{
ll tmp = l[i] + r[i] - a[i];
if (tmp > res) { res = tmp; id = i; }
} for (int i = id - 1; i >= 1; i--) a[i] = min(a[i], a[i + 1]);//摊平峰左侧
for (int i = id + 1; i <= n; i++) a[i] = min(a[i], a[i - 1]);//摊平峰右侧 for (int i = 1; i <= n; i++) cout << a[i] << " "; return 0;
}

代码参考自:knight_wang

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)(单调栈,递推)的更多相关文章

  1. Codeforces Round #622 (Div. 2) C2 - Skyscrapers (hard version) 单调栈

    从左往右扫,找到比第i个小的第一个数字,l[i] = l[last] + (i - last) * m[i],用单调栈O(n)维护这个过程,再从右往左扫,同理可以算出r数组,注意一下long long ...

  2. Codeforces Round #622 (Div. 2).C2 - Skyscrapers (hard version)

    第二次写题解,请多多指教! http://codeforces.com/contest/1313/problem/C2 题目链接 不同于简单版本的暴力法,这个数据范围扩充到了五十万.所以考虑用单调栈的 ...

  3. Codeforces Round #622 (Div. 2)C2 Skyscrapers最大"尖"性矩形,思维||分治

    题:https://codeforces.com/contest/1313/problem/C2 题意:给出n个数,分别代表第i个位置所能搭建的最大高度,问以哪一个位置的塔的高度为基准向左的每一个塔都 ...

  4. Codeforces Round #622(Div 2) C1. Skyscrapers (easy version)

    题目链接: C1. Skyscrapers (easy version) 题目描述: 有一行数,使得整个序列满足 先递增在递减(或者只递增,或者只递减) ,每个位置上的数可以改变,但是最大不能超过原来 ...

  5. Codeforces Round #622 (Div. 2) C1. Skyscrapers (easy version)(简单版本暴力)

    This is an easier version of the problem. In this version n≤1000n≤1000 The outskirts of the capital ...

  6. Codeforces Round #305 (Div. 1) B. Mike and Feet 单调栈

    B. Mike and Feet Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/547/pro ...

  7. Codeforces Round #622 (Div. 2)C2

    题意 N长度为500000以内,一个数字两边的数字不能都比他高,最多高一边 求他最大sum.叙述有问题,直接看样例 3 10 6 8 因为6左右都比他高,选择10 6 6或者6 6  8,sum明显前 ...

  8. Codeforces Round #172 (Div. 2) D. Maximum Xor Secondary 单调栈应用

    http://codeforces.com/contest/281/problem/D 要求找出一个区间,使得区间内第一大的数和第二大的数异或值最大. 首先维护一个单调递减的栈,对于每个新元素a[i] ...

  9. Codeforces Round #305 (Div. 2) D. Mike and Feet 单调栈

    D. Mike and Feet time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

随机推荐

  1. 【Linux】CentOS8 初体验

    一.部署CentOS8虚拟机 1.下载Centos8镜像 下载地址: https://www.centos.org/download/ 可以选择国内的下载源,比较快,这里推荐清华的和阿里的 2.下载完 ...

  2. ctfhub技能树—信息泄露—svn泄露

    打开靶机 查看页面信息 使用dvcs-ripper工具进行处理 ./rip-svn.pl -v -u http://challenge-3b6d43d72718eefb.sandbox.ctfhub. ...

  3. C#使用struct直接转换下位机数据

    编写上位机与下位机通信的时候,涉及到协议的转换,比较多会使用到二进制.传统的方法,是将数据整体获取到byte数组中,然后逐字节对数据进行解析.这样操作工作量比较大,对于较长数据段更容易计算位置出错. ...

  4. 环境配置-Java-02-卸载

    1.卸载程序 在windows程序与功能中卸载Java相关的两个程序 2.删除环境变量 在windows环境变量中删除JAVA_HOME.CLASSPATH 以及 PATH中的两条路径 3.查看是否卸 ...

  5. 翻译 - ASP.NET Core 基本知识 - 中间件(Middleware)

    翻译自 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0 中间件是集成 ...

  6. spring boot 集成 websocket 实现消息主动

    来源:https://www.cnblogs.com/leigepython/p/11058902.html pom.xml 1 <?xml version="1.0" en ...

  7. mysql 1449 : The user specified as a definer ('usertest'@'%') does not exist 解决方法 (grant 授予权限)

    从服务器上迁移数据库到本地localhost 执行  函数  时报错, mysql 1449 : The user specified as a definer ('usertest'@'%') do ...

  8. 事件循环Event loop到底是什么

    摘要:本文通过结合官方文档MDN和其他博客深入解析浏览器的事件循环机制,而NodeJS有另一套事件循环机制,不在本文讨论范围中.process.nextTick和setImmediate是NodeJS ...

  9. 设置一个两边固定中间自适应的css

    1.两边浮动,中间自动宽度 给左右两个盒子设置左右浮动,中间的盒子不设置宽度,左右两边边距为左右盒子的宽度,中间盒子的位置必须写在右盒子下面,不然会把右盒子挤下去 如:   <div class ...

  10. Java Socket实战之七 使用Socket通信传输文件

    http://blog.csdn.net/kongxx/article/details/7319410 package com.googlecode.garbagecan.test.socket.ni ...