単調なスタック--POJ - 2796

タイトルの意味

あなたは、いくつかの隣接番号を見つけるしたい杭の数、与えられました

彼らと彼らの最小値は、すべての最大の数を乗じて

第1の出力値と座標とその取得した番号の最後の数字の座標

トピック分析

式は次のとおりです。これらの数字とこれらの数字は最小で乗算されています

同じ最小値と(ゼロより数が大きいため)ので、カウント数が良いです

その後、我々は小から大に最小値に応じて、最小間隔が分割さに応じて検討することができます

この場合、隣接する部分ABは、最小値bの最小値未満であります

最小間隔bの値と代表のB、Bを乗じた答えと比較して、値の範囲を取得するように更新間隔は、それが大きくなった場合

そして、間隔の範囲の範囲内に統合B、それは我々が表現を乗じた最小間隔の後にそれをカウントしなければならないことを意味します

[N + 1] -1が割り当てられるので、合計間隔の値を更新することができることに注意してください

トピックコード

書式#include <stdio.hに> 
する#include <iostreamの> 
書式#include <math.h>の
書式#include < 文字列の.h> 
の#include <アルゴリズム>
 使用して 名前空間はstdを、
typedefの長い 長いLL。
const  int型 MAXN = 1E5 + 7 int型N、トップ、Q [MAXN]、左[MAXN]、LL、RR。
LL [MAXN]和[MAXN]、ANS。
INT メイン(){ 
    scanf関数(" %のD "、&N)
    以下のためにint型 i = 1 ; iは++; iが= N < 
        (scanf関数を"LLDの%、&​​A [I])、SUM [I]は= SUM [I- 1 ] + [I]、
    トップ = 0、ANS = - 1。; 
    [ ++ N-] = - 1。;
     のためのint型 I = 1 ; I <= N; Iは++ ){
         IF(トップ== 0 || A [Q [トップ] < A [I]){ 
            Q [ ++トップ] = I; 
            左[I] = I; / // 最初の部分の座標の数の数を表すが必要
            続行; 
        } 
        IF([I] == A [Q [トップ]])続行し一方(トップ> 0&& [Q [トップ]> [I]){ 
            LLのTEMP =(SUM [I- 1 ] -sum [左[Q [トップ]] - 1 ])* [Q [トップ]。
            もし(TEMP> ANS){ 
                ANS = TEMP。
                RR = I- 1 
                LL = 左の[Q [トップ]。
            } 
            トップ - 
        } 
//         のQ [++トップ] = I。
        左の[I] =左[Q [++ トップ]。
        Q [トップ] = I。
    } 
    のprintf(" %LLDする\ n%D%D \ n "、ANS、LL、RR)。
    リターン 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/helman/p/11222359.html