HDU 5696 區間的價值
阿新 • • 發佈:2019-01-30
我們定義“區間的價值”為一段區間的最大值*最小值。
一個區間左端點在L,右端點在R,那麼該區間的長度為(R−L+1)。
現在聰明的傑西想要知道,對於長度為k的區間,最大價值的區間價值是多少。
當然,由於這個問題過於簡單。
我們肯定得加強一下。
我們想要知道的是,對於長度為1∼n的區間,最大價值的區間價值分別是多少。
一個區間左端點在L,右端點在R,那麼該區間的長度為(R−L+1)。
現在聰明的傑西想要知道,對於長度為k的區間,最大價值的區間價值是多少。
當然,由於這個問題過於簡單。
我們肯定得加強一下。
我們想要知道的是,對於長度為1∼n的區間,最大價值的區間價值分別是多少。
分析:列舉以該點為最小值,然後找到最大值,更新,相應陣列,至此,把區間分割(因為包含這個最小值點已經列舉過),遞迴寫法即可
#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; }