Codeforces 1201D。宝探し

ポータル

気持ちを見ては、$ DP $ですが、それは国家のあまり思わ

自然を押して考えてみましょう

まず、すべての宝物を置く必要があり、すべての行が来て、我々は左端と右端の宝物になります

完成したときに宝の場所が気づいたら、すべての宝物は、左端または右端でなければなりません

あなたは、道路上で遠くに行くことを選択した場合にも上った後、遠くその場所に行ってきました可能性があるため、この時間は、明らかに左または右に最も近い道を選択し、上に移動します

だから我々は、我々は、各フロアにのみ4つの選択肢があることを見つける:左端の2、最高の最近約2右端の宝物最近の回復基調の宝物について

4箇所に直接それぞれの層の前処理した後、0,1,2,3の数字の$ $

[I] [4] $が完了し、第1の層と$ $ I $ I $の宝第一の層を表し、fは次に、DPは位置に、次のレベルの準備ができて、この時間は直接$にある$を、$安全にすることができます$ 0/1/2/3 $の

直接左端または右端最初に1階の仕上げを分類することができますどのような議論します

私たちは最後まで仕上げの最高層一度宝の存在に注意を払う、としないように準備ができて、さらに高いレベルなので、最後の層は、特別な処理、それに転送される必要があります

詳細の多くは慎重に指すように

#include <iostreamの> 
する#include <cstdioを> 
する#include <アルゴリズム> 
の#include <CStringの> 
する#include <cmath> 
の#include <ベクトル>
 使用して 名前空間STD。
typedefの長い 長いLL。
インラインint型リード()
{ 
    int型のx = 0、F = 1チャー CH = GETCHAR()。
    一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - '1 ; CH = GETCHAR()。}
     一方、(CH> = ' 0 ' && CH <= ' 9 '){X =(X << 1)+(X << 3)+(CH ^ 48)。CH = GETCHAR()。}
     戻りのx *のF。
} 
のconst  int型 N = 4E5 + 7 constの LL INF = 1E18; 
LLのN、M、K、Q、B [N]、L [N]、R [N]。
LL事前[N]、NXT [N]、POS [N] [ 4 ]。
LL F [N] [ 4 ]。
インラインLL計算値(LL sで、LL Tと、int型のI)
{ 
    場合(S < 1|| S> M || T < 1 || T> M)戻り INF。//
     もし(!R [i])とリターン ABS(ST); //
     戻り分(ABS(SL [I])+ ABS(L [I] -R [I])+ ABS(R [I] -t)、ABS(SR [I])+ ABS(L [I]を-R [I])+ ABS(L [I] - T))。
} 
int型のmain()
{ 
    N =、Qは=)()(M = read()は、Kが=リードを読み出す(リード)。
    LL X、Y。memsetの(L、0x3fをはsizeof (L))。
    以下のためにint型 i = 1 ; iが= Kを<; Iは++ 
    { 
        X =読み取る()、Yは= )(読み取ります。
        L [X] =分(L [x]は、Y)。R [X] =MAX(R [X]、Y); 
    } 
    のためにint型 I = 1 ; I <= Q; iは++)[I]は= B 読み取ります();
    INTは L = 0、R = 1ソート(B + 1、B + 1 Q + 1)。B [Q + 1 ] = M + 1 以下のためにint型私= 1 ; I <= M; iが++ 
    { 
        一方(B [L + 1 ] <= I)L ++ 一方、(B [R] <I)R ++ 
        事前[I] = bの[L]。NXT [I] =のB [R]。
    } 
    のためのINT I = 1; iが<= N; iは++ 
    { 
        場合(L [i]が<= M)POS [I] [ 0 ] =予備[L [I]、POS [I] [ 1 ] = NXT [L [I] ;
        もし(R [I]> = 1)POS [I] [ 2 ] =予備[R [I]、POS [I] [ 3 ] = NXT [R [I]]。
    } 
    のmemset(F、0x3fをはsizeof (F))。
    INTプリ= 1、prre = 0 以下のためにint型 i = 0 ; iは< 4 iは++; 場合(R [事前])F [事前] [I] = CALC(1 、POS [事前] [I]、PRE)。
         F [事前] [I] = NXT [ 1 ] - 1、POS [事前] [I] = NXT [ 1 ]。//
     のためのint型 iは=プリ+ 1 ; iが<= N iが++ 
    { 
        場合(R [i]が!)続けますint型 J = 0 ; J < 4 ; J ++ のためのINT K = 0 ; K < 4 ; kは++ 
                F [i]は[J] =分(F [I] [J]、F [事前] [K ] +計算値(POS [事前] [K]、POS [I]、[J]、I)+(I- PRE))。
        prre =前; 予備= I;
    } 
    LLアンス = INF。
    もし(!prre){のprintf(" %LLDする\ n "、R [事前] - 1)。リターン 0 ; } //
     のためのint型のk = 0 ; K < 4 ; kは++ 
        アンス =分(ANS、F [prre] [K] +(プレprre)+分(ABS(POS [prre] [K] -L [プレ])、ABS(POS [prre] [K] -R [事前]))+(R [事前] -L [事前]))。//
     printfの(" %LLDの\ nを" 、ANS)。
    リターン 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/LLTYYC/p/11597504.html