• CF1313C2 Skyscrapers (hard version) (单调栈)


    Skyscrapers (hard version)

    思路:我们需要维护当下标为inx的大楼为最高的时候,两边大楼的情况。我们可以把下标为inx的大楼最高时,分别统计左边和右边的情况,我们可以用单调栈维护最小值(小->大),如果栈顶的元素的高度小于inx的大楼,说明之前的所有大楼都因为栈顶的大楼而小于了inx的大楼的高度,如果栈顶的大楼高度大于等于inx的大楼,则说明栈顶下面第一个的大楼到栈顶的大楼之间的大楼需要改变为inx大楼的高度,需要注意空栈的情况。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <functional>
      5 #include <set>
      6 #include <vector>
      7 #include <queue>
      8 #include <cstring>
      9 #include <stack>
     10  
     11 using namespace std;
     12  
     13 #define ll long long
     14 #define pb push_back
     15 #define fi first
     16 #define se second
     17  
     18  
     19 void solve(){
     20     int n;
     21     cin >> n;    
     22     vector<int > a(n);
     23     for(auto& in : a) cin >> in;
     24     stack<int > Sta;
     25     vector<ll > pre(n);
     26     for(int now = 0; now < n; ++now){
     27         while(!Sta.empty()){
     28             int top = Sta.top();
     29             if(a[top] >= a[now]){
     30                 Sta.pop();
     31                 if(!Sta.empty()){
     32                     pre[now] += (ll)a[now] * (top - (int)Sta.top());
     33                 }else {
     34                     pre[now] += (ll)a[now] * (top + 1);
     35                 }
     36             }else {
     37                 pre[now] += pre[top];
     38                 break;
     39             }
     40         }
     41         Sta.push(now);
     42         pre[now] += a[now];
     43     }
     44     // for(int i = 0; i < n; ++i) cout << pre[i] << " ";
     45     // cout << endl;
     46     vector<ll > rpre(n);
     47     while(!Sta.empty()) Sta.pop();
     48     vector<int > cp(a);
     49     reverse(a.begin(), a.end());
     50     for(int now = 0; now < n; ++now){
     51         while(!Sta.empty()){
     52             int top = Sta.top();
     53             if(a[top] >= a[now]){
     54                 Sta.pop();
     55                 if(!Sta.empty()){
     56                     rpre[now] += (ll)a[now] * (top - (int)Sta.top());
     57                 }else {
     58                     rpre[now] += (ll)a[now] * (top + 1);
     59                 }
     60             }else {
     61                 rpre[now] += rpre[top];
     62                 break;
     63             }
     64         }
     65         Sta.push(now);
     66         rpre[now] += a[now];
     67     }
     68     // for(auto& x : rpre) cout << x << " ";
     69     // cout << endl;
     70     int inx = 0;
     71     //cp[i]被算了两次,需要减去一次
     72     for(int i = 1; i < n; ++i){
     73         inx = (pre[i] + rpre[n - 1 - i] - cp[i] > pre[inx] + rpre[n - 1 - inx]  - cp[inx] ? i : inx);
     74     }
     75     // cout << "inx = " << inx << endl;
     76     int Min = cp[inx];
     77     vector<int > ans(n);
     78     for(int i = inx; i >= 0; --i){
     79         Min = min(Min, cp[i]);
     80         ans[i] = Min;
     81     }
     82     Min = cp[inx];
     83     for(int i = inx + 1; i < n; ++i){
     84         Min = min(Min, cp[i]);
     85         ans[i] = Min;
     86     }
     87     for(auto x : ans) cout << x << " ";
     88     cout << endl;
     89  
     90 }
     91  
     92 int main(){
     93     
     94     ios::sync_with_stdio(false);
     95     cin.tie(0);
     96     cout.tie(0);
     97     solve();
     98     
     99     return 0;
    100 }
  • 相关阅读:
    Windows下使用CMake编译SuiteSparse成VS工程
    【设计模式
    【设计模式
    vue过滤和复杂过滤
    el-tooltip 自定义样式
    el-table加表单验证
    使用Go env命令设置Go的环境
    面试官:GET 和 POST 两种基本请求方法有什么区别?
    解决 Vue 重复点击相同路由报错的问题
    利用promise和装饰器封装一个缓存api请求的装饰器工具
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12791310.html
Copyright © 2020-2023  润新知