• Codeforces Round #622 (Div. 2)C(单调栈,DP)


    构造出的结果一定是一个单峰/这种样子的

     1 #define HAVE_STRUCT_TIMESPEC
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 long long a[500007];
     5 pair<long long,long long>stk[500007];
     6 long long l[500007],r[500007];//记录左/右边最近的比当前小的位置
     7 long long ans[500007];
     8 long long dp[5][500007];//dp[0][i]表示当a[i]在1~i上单调增时,高度的前缀和,dp[1][i]表示a[i]在i~n单调减时,高度的后缀和(单调可以平,相邻可以相等)
     9 int main(){
    10     ios::sync_with_stdio(false);
    11     cin.tie(NULL);
    12     cout.tie(NULL);
    13     int n;
    14     cin>>n;
    15     for(int i=1;i<=n;++i)
    16         cin>>a[i];
    17     int cnt=0;
    18     for(int i=1;i<=n;++i){
    19         if(cnt==0||stk[cnt].first<a[i])
    20             stk[++cnt]=make_pair(a[i],i);
    21         while(cnt>0&&stk[cnt].first>=a[i]){
    22             l[stk[cnt].second]=stk[cnt-1].second;
    23             r[stk[cnt].second]=i;
    24             --cnt;
    25         }
    26         stk[++cnt]=make_pair(a[i],i);
    27     }
    28     while(cnt){
    29         l[stk[cnt].second]=stk[cnt-1].second;
    30         r[stk[cnt].second]=1+n;
    31         --cnt;
    32     }
    33     for(int i=1;i<=n;++i)
    34         if(a[i]>a[i-1])
    35             dp[0][i]=dp[0][i-1]+a[i];
    36         else//前面比自己大
    37             dp[0][i]=dp[0][l[i]]+(i-l[i])*a[i];//找到i左边最近的比它小的,l[i]~i之间全都砍为a[l[i]]
    38     for(int i=n;i;--i)
    39         if(a[i]>a[i+1])
    40             dp[1][i]=dp[1][i+1]+a[i];
    41         else//后面比自己大
    42             dp[1][i]=dp[1][r[i]]+(r[i]-i)*a[i];//找到i右边最近的比它小的,i~r[i]之间全都砍为a[r[i]]
    43     long long mx=0,pos=0,now=0;
    44     for(int i=1;i<=n;++i)
    45         if(dp[0][i]+dp[1][i]-a[i]>mx){
    46             mx=dp[0][i]+dp[1][i]-a[i];
    47             pos=i;
    48         }
    49     ans[pos]=a[pos];
    50     now=a[pos];
    51     for(int i=1+pos;i<=n;++i)
    52         if(a[i]>=now)
    53             ans[i]=now;
    54         else{
    55             ans[i]=a[i];
    56             now=a[i];
    57         }
    58     now=a[pos];
    59     for(int i=pos-1;i;--i)
    60         if(a[i]>=now)
    61             ans[i]=now;
    62         else{
    63             ans[i]=a[i];
    64             now=a[i];
    65         }
    66     for(int i=1;i<=n;++i)
    67         cout<<ans[i]<<" ";
    68     return 0;
    69 }
    保持热爱 不懈努力 不试试看怎么知道会失败呢(划掉) 世上无难事 只要肯放弃(划掉)
  • 相关阅读:
    软件工程个人作业01
    学习进度一(2017/12/2)
    课程增加功能(java web)
    剑指offer-把数组排成最小的数
    论文-Edge Boxes
    论文-Selective Search
    剑指offer-机器人的运动范围
    leetcode-539-Minimum Time Difference
    Leetcode-543-Diameter of Binary Tree
    论文-SSD-Single Shot MultiBox Detector
  • 原文地址:https://www.cnblogs.com/ldudxy/p/12365462.html
Copyright © 2020-2023  润新知