码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)(单调栈,递推)

时间:2020-03-19 21:25:05      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:www   递增栈   amp   min   code   tmp   pre   单调栈   color   

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)(单调栈,递推)

标签:www   递增栈   amp   min   code   tmp   pre   单调栈   color   

原文地址:https://www.cnblogs.com/Kanoon/p/12527089.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!