通过枚举每个点作为最小值,再通过动态规划求出以每个点作为最小值的左右区间。
代码如下:
#include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #define MAXN 100005 using namespace std; typedef long long int Int64; Int64 seq[MAXN], sum[MAXN], ret; int L[MAXN], R[MAXN], N; int main() { while (scanf("%d", &N) == 1) { ret = -(1LL << 60); for (int i = 1; i <= N; ++i) { scanf("%I64d", &seq[i]); sum[i] = sum[i-1] + seq[i]; } for (int i = 1; i <= N; ++i) { int len = 0, j = i - 1; while (j >= 1) { if (seq[j] < seq[i]) break; len += L[j] + 1; j = i - len - 1; } L[i] = len; } for (int i = N; i >= 1; --i) { int len = 0, j = i + 1; while (j <= N) { if (seq[j] < seq[i]) break; len += R[j] + 1; j = i + len + 1; } R[i] = len; } for (int i = 1; i <= N; ++i) { ret = max(ret, (sum[i+R[i]]-sum[i-L[i]-1]) * seq[i]); } printf("%I64d\n", ret); } return 0; }