HDU-5696-区间的价值(DFS)

来源:互联网 发布:怀孕软件哪个好 编辑:程序博客网 时间:2024/06/05 03:58

题目链接: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


题解:找到当前区间(l,r)的最大值与最小值,当前区间解为最大值*最小值,

以最小值分割区间为a,b两部分,对于最大值所在的区间长度len显然一定有ans[r-l+1]<=ans[len];

所以直接分区间更新最优解就好。  


#include <bits/stdc++.h>//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>#include <algorithm>using namespace std;#define INF 0x3f3f3f3f#define LINF 0x3f3f3f3f3f3f3f3f#define LL long long#define bug cout<<"bug"<<endlconst int MAXN = 1e6+7;long long a[MAXN],ans[MAXN];int n;void getmax(long long &x, long long y){x=max(x,y);}void DFS(int l, int r){    if(l>=r)return ;    long long pmin=LINF,pmax=0;    int p1,p2;    for(int i=l; i<=r; ++i)    {        if(pmin>a[i]){pmin=a[i];p1=i;}        if(pmax<a[i]){pmax=a[i];p2=i;}    }    getmax(ans[r-l+1],a[p1]*a[p2]);    int p=(p2<p1)?p1-l:r-p1;    for(int i=p+1; i<r-l+1; ++i)        getmax(ans[i],ans[r-l+1]);    DFS(l,p1-1);    DFS(p1+1,r);}int main(){    while(~scanf("%d",&n))    {        memset(ans,0,sizeof(ans));        for(int i=0; i<n; ++i)        {            scanf("%I64d",&a[i]);            getmax(ans[1],a[i]*a[i]);        }        DFS(0,n-1);      //  for(int i=n-1; i>=2; --i)          //  getmax(ans[i],ans[i+1]);        for(int i=1; i<=n; ++i)            printf("%I64d\n",ans[i]);    }    return 0;}/*51 6 2 4 4*/


0 0
原创粉丝点击