HDU 5696 区间的价值 暴力

区间的价值

题目连接:

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();
}
posted @ 2016-05-24 09:32  qscqesze  阅读(983)  评论(3编辑  收藏  举报