気持ちを見ては、$ 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 ; }