使用dp[i,j]表示区间【i,j】能得到计算值的最大值
k表示区间【i,j】的最小值min的下标索引
则序列结构可表示如下:
【i,k-1】【min】【k+1,j】
【i,j】所有子区间分为两种情况:包含min、不包含min
在所有包含min的子区间【m,n】中,计算值:
min∗sum[m,n]<=min∗sum[i,j]
所以:
dp[i,j]=max⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪min∗sum[i,j]dp[i,k−1]dp[k+1,j]
#include <stdio.h>
#include <vector>
#include <numeric>
#include <algorithm>
#include <iostream>
using namespace std;
//#define debug_
typedef vector<int>::iterator vec_iter;
int n;
vector<int> vec;
long long func(vec_iter left, vec_iter right)
{
if ((left) == right)
{
if (left != vec.end())
{
return (*left)*(*left);
}
else
{
return -1;
}
}
if ((left+1) ==right)
return (*left)*(*left);
auto min_iter = min_element(left, right);
long long R_1 = accumulate(left, right, 0)*(*min_iter);
long long R_2 = func(left, min_iter);
long long R_3 = func(min_iter+1, right);
return max(R_1, max(R_2, R_3));
}
int main()
{
#ifdef debug_
n = 7;
vec.push_back(2);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
vec.push_back(6);
vec.push_back(1);
#else
cin >> n;
vec.resize(n);
for (auto i = 0; i < n;++i)
{
cin>>vec[i];
}
#endif
cout<<func(vec.begin(),vec.end());
return 0;
}