ポータル:https://www.luogu.org/problemnew/show/P2893
タイトル「修理がB_i、コストになった後、道路の各区間の元の上昇は、a_iをある| a_iを- B_i |。我々は、道路の補修需要最小限のコストの上昇または低下しない単調単調ではない..です必要」一見シーケンス(当然ではない)、これは比較的単純な線形DPのタイトル・トラックであるように立ち上がります。まず、有効な解決策は、構築されたシーケンスBなどがその∀x∈Bx∈Aを満たさなければなりません
そうB配列が連続セグメントXの複数(x∈A)から構成されている必要があり、次いで、第1の離散消費を低減させる、F [I] [j]は番号iの前に実行されて設けられ、jが最後の数であります最小のコスト、があります。
F [I] [J] =分(F [I-1] [K] + | A [i]が-j |)。
時間計算量は、O(N ^ 2)でタイムアウトしません。
書式#include <cstdioを> する#include <iostreamの> の#include <アルゴリズム> 書式#include <cmath> の#include <キュー> の#include <CStringの> の#include <ベクトル> 使用して 名前空間はstd; const int型 MAXN = 2005 ; INT [MAXN]、NUM [MAXN]、[MAXN] C。 INT [MAXN] [MAXN] F。 int型のn; INT メイン(){ scanf関数(" %のD "、&N) 以下のために(int型 I = 1 iは= N <; I ++は){ (scanf関数を " %のD "、および[I])。 NUM [I] = [i]は、 } ソート(NUM + 1、NUM + N + 1 )。 INT、M =ユニーク(NUM + 1、NUM + N + 1) - NUM - 1 。 以下のために(int型 i = 1 ; iが<= N; iが++ ) C [I] = LOWER_BOUND (NUM + 1、NUM + N + 1、[I]) - NUM。 memsetの(F、0x3fを、はsizeof(f)参照)。 F [ 0 ] [ 0 ] = 0 。 以下のために(int型 i = 1 ; iが<= N; iは++ ){ int型の TEMP = F [I - 1 ] [ 0 ]。 用(INT J = 1 ; J <= Mであり、j ++ ){ TEMP =分(F TEMP、[I - 1 ] [J])。 F [I] [J] = TEMP + ABS([I] - NUM [J])。 } } int型 ANS = 1 << 30 。 以下のための(int型I = 1 ; I <= M。I ++ ) ANS = 分(ANS、F [n]は[I])。 printf(" %d個の\ n " 、ANS)。 リターン 0 ; }