区间的价值
题目连接:
http://acm.hdu.edu.cn/showproblem.php?pid=5696
Description
我们定义“区间的价值”为一段区间的最大值*最小值。
一个区间左端点在L,右端点在R,那么该区间的长度为(R−L+1)。
现在聪明的杰西想要知道,对于长度为k的区间,最大价值的区间价值是多少。
当然,由于这个问题过于简单。
我们肯定得加强一下。
我们想要知道的是,对于长度为1∼n的区间,最大价值的区间价值分别是多少。
样例解释:
长度为1的最优区间为2−2 答案为6∗6
长度为2的最优区间为4−5 答案为4∗4
长度为3的最优区间为2−4 答案为2∗6
长度为4的最优区间为2−5 答案为2∗6
长度为5的最优区间为1−5 答案为1∗6
Input
多组测试数据
第一行一个数n(1≤n≤100000)。
第二行n个正整数(1≤ai≤109),下标从1开始。
由于某种不可抗力,ai的值将会是1∼109内随机产生的一个数。(除了样例)
Output
输出共n行,第i行表示区间长度为i的区间中最大的区间价值。
Sample Input
5
1 6 2 4 4
Sample Output
36
16
12
12
6
Hint
题意
题解:
数据全随机有什么好说的呢?n^2的算法很显然,剪剪枝就过了
直接暴力枚举哪一个数是这个区间的最大值就好了
然后左右扩展,然后暴力莽一波就好了……
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+6;
int n;
long long a[maxn];
long long dp[maxn];
void solve()
{
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
{
dp[1]=max(dp[1],a[i]*a[i]);
int l=i,r=i;
long long Min=a[i];
while(1)
{
if(r-l+1==n)break;
if((l!=1)&&(r==n||a[l-1]>a[r+1]))Min=min(Min,a[--l]);
else Min=min(Min,a[++r]);
if(a[l]>a[i]||a[r]>a[i])break;
dp[r-l+1]=max(dp[r-l+1],a[i]*Min);
}
}
for(int i=1;i<=n;i++)printf("%lld\n",dp[i]);
}
int main()
{
while(scanf("%d",&n)!=EOF)
solve();
}