08月29日, 2015 1,952 views次
题意
给出一个长度为n的正整数序列ai,求出一段连续子序列al~ar,使得sum(al~ar)*min(al~ar)最大
分析
对于每个数字ai,当他作为最小值时有最优解当且仅当l,r分别取到大于等于ai的最左和最右边。递归找出这样的边界,然后枚举最小值求出最优解即可。
CPP代码
#include <bits/stdc++.h> using namespace std; using ll = long long; const int maxn = 102400; int kase, n, v[maxn],l[maxn], r[maxn]; ll sum[maxn]; void input() { for(int i = 1; i <= n; ++i) { cin >> v[i]; sum[i] = sum[i-1] + v[i]; l[i] = r[i] = i; } v[0] = v[n+1] = -1; for(int i = n; i >= 1; --i) while(v[r[i]+1] >= v[i]) r[i] = r[r[i]+1]; for(int i = 1; i <= n; ++i) while(v[l[i]-1] >= v[i]) l[i] = l[l[i]-1]; } void solve() { ll best = 0, L = 1, R = 1; for(ll i = 1; i <= n; ++i) { ll cur = v[i] * (sum[r[i]] - sum[l[i]-1]); if(cur > best) { best = cur; L = l[i], R = r[i]; } } cout << best << endl << L << " " << R << endl; } int main() { ios::sync_with_stdio(false); while(cin >> n) { if(kase++) cout << endl; input(); solve(); } return 0; }