通过枚举每个点作为最小值,再通过动态规划求出以每个点作为最小值的左右区间。
代码如下:
#include#include #include #include #define MAXN 100005using 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; }