给定一个数组A,构造一个数组B,满足,B先增再减(或者只增,只减), 且 bi <= ai
使得∑bi最大
#include <algorithm>
#include <vector>
#include <stack>
#define ll long long
#define PII pair<int, int>
#define FOR(i, s, e) for (int i = s; i <= e;i++)
#define ROF(i, e, s) for (int i = e; i >= s;i--)
#define debug(a) cout << #a << "=" << a << endl;
#define pb(a) push_back(a)
#define endl '\n'
#define INF 0x3f3f3f3f
#define LNF 0x3f3f3f3f3f3f3f3f
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 7;
void init_code(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
}
ll a[N],n;
int nex[N],prv[N];
ll f[N],fl[N],fr[N];
void NLE(){
a[0]=-INF,a[n+1]=-INF; // 设置默认值
stack<int>st;
//求nxt
FOR(i,1,n+1){
while(!st.empty() && a[st.top()]>a[i]){
nex[st.top()]=i; st.pop();
} st.push(i);
} st.pop();
//求prv
ROF(i,n,0){
while(!st.empty() && a[st.top()]>a[i]){
prv[st.top()]=i; st.pop();
} st.push(i);
} st.pop();
}
int main(int argc, char const *argv[])
{
init_code();
cin>>n;
FOR(i,1,n)cin>>a[i];
// 求nxt,prv数组
NLE();
//dp
FOR(i,1,n){ int j=prv[i]; fl[i]=a[i]*(i-j) + fl[j]; }
ROF(i,n,1){ int j=nex[i]; fr[i]=a[i]*(j-i) + fr[j]; }
FOR(i,1,n){ f[i]=fl[i]+fr[i]-a[i]; }
//求具体方案
int id=max_element(f+1,f+1+n)-f;
ROF(i,id-1,1)a[i]=min(a[i],a[i+1]);
FOR(i,id+1,n)a[i]=min(a[i],a[i-1]);
FOR(i,1,n){ cout<<a[i]<<" "; }
return 0;
}