说是动态规划的题,但是说实话我没看出来
我的做法是找出当前位置左侧比a[i]高的个数l[i]和右侧比a[i]高的个数r[i]
二重循环,因为n最大为1e5,因此O(n*n)超时
看了别人的代码,虽然想法一样,但是找的不是两侧比当前高度高的个数,而是边界下标
比如第i个位置左侧比a[i]高度高的边界下标是l[i]==j,那么寻找第i+1个位置的左侧高度下标边界时
若a[i]>=a[i+1],那么直接判断a[l[i]]和a[i+1],因为j到i之间的高度都比a[i]高,因此必然比a[i+1]高
代码如下:
#include <iostream>
#include <cstdio>
#define ll long long
#define MAXN 100010
using namespace std;
ll a[MAXN];
ll l[MAXN];
ll r[MAXN];
int main(void){
int n;
int t;
while(cin >> n, n){
for(int i=1; i<=n; ++i){
scanf("%d", &a[i]);
}
l[1] = 1;
r[n] = n;
for(int i=2; i<=n; ++i){
t = i;
while(t>1 && a[i]<=a[t-1]){
t = l[t-1];
}
l[i] = t;
// cout << "l[" << i << "] = " << l[i] << endl;
}
for(int i=n-1; i>0; --i){
t = i;
while(t<n && a[i]<=a[t+1]){
t = r[t+1];
}
r[i] = t;
// cout << "r[" << i << "] = " << r[i] << endl;
}
ll maxdp = 0;
for(int i=1; i<=n; ++i){
maxdp = max(maxdp, (r[i]-l[i]+1)*a[i]);
}
cout << maxdp << endl;
}
}