1. 程式人生 > >HDU 5696 區間的價值

HDU 5696 區間的價值

我們定義“區間的價值”為一段區間的最大值*最小值。

一個區間左端點在L,右端點在R,那麼該區間的長度為(RL+1)

現在聰明的傑西想要知道,對於長度為k的區間,最大價值的區間價值是多少。

當然,由於這個問題過於簡單。

我們肯定得加強一下。

我們想要知道的是,對於長度為1n的區間,最大價值的區間價值分別是多少。

分析:列舉以該點為最小值,然後找到最大值,更新,相應陣列,至此,把區間分割(因為包含這個最小值點已經列舉過),遞迴寫法即可

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF  0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-10
#define maxn 1000010
#define MOD 1000000007
typedef long long LL;
const int N=1e5+5;
int a[N],n;
LL res[N];
void dfs(int l,int r){
    if(l>r)return;
    if(l==r){res[1]=max(res[1],1ll*a[l]*a[l]);return;}
    int k1,k2;k1=k2=l;
    for(int i=l;i<=r;++i){
        if(a[i]<a[k1])k1=i;
        if(a[i]>a[k2])k2=i;
    }
    res[r-l+1]=max(res[r-l+1],1ll*a[k1]*a[k2]);
    dfs(l,k1-1);
    dfs(k1+1,r);
}
int main(){
    while(~scanf("%d",&n)){
       for(int i=1;i<=n;++i)
         scanf("%d",&a[i]),res[i]=0;
       dfs(1,n); 
       for(int i=n-1;i>0;--i)
         res[i]=max(res[i],res[i+1]);
       for(int i=1;i<=n;++i)
        printf("%I64d\n",res[i]);
    }
    return 0;
}