私はパートを思い付いたこの質問は、努力の必要性を示し、来ていない別の部分があります。
私は私が最終的に番号j(高さ)は、コストの最小値を得ることができる前に、番号を変更するための第1のD(i、j)で表すことについて話をする最初の部分は、これが考えることは困難ではないと思います、
しかし、N <= ^ 9 10ので、それは時間と空間の面で実現可能であるので、jがかかる場合状態の定義を変更する必要性は、私が思うに、この質問の高さは、Jの特別な値でなければなりません
どれがどうなる、それはスペースを省略することはできません、それは一番下に、前の、同じ(範囲内であれば)の最上部の高さであってもよく、その後、出てこない何を思いました。
私の考えでは、我々は上、中、下の(実際には3つの数字を証明することができる見ることが容易でなければならない数3の例を引用することができ、正しいが、昇進や拡張で後方に乏しく、
、私は高さだけ知っていた)私はより多くのを許可しませんが、ゲーム中に時々この気持ちは、多くの場合、権利で前の、不変、下のトップで、全体のために考えていませんでした
値の法則の高された後、本を説明することで、私もそう状態の私達の数はO(^ 3 n)がなり、変更のすべての特定の数は、HP + KDフォームを書くことができることを理解します(他のブログを見ることができます)上記の、そしてそこに単調キューがある(またはスライディングウィンドウデータ構造を使用)、これは非常に巧妙で、彼は償却時間複雑性はO(1)書籍(Iであります
私は何償却時間の複雑さを知らないのか?)、そして、(スライディングウィンドウ)を実装悪い書き込みを感じて、それは(学んだ)劉Rujiaコードは非常に賢い見つけているようだ、次のとおりであります
コード:
// UVA 12170 の#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> 使用して 名前空間はstdを、 typedefの長い 長いLL。 const int型 MAXN = 100 + 5 。 const int型 MAXX = MAXN * MAXN * 2 。 CONST LL INF =(1LL << 60 )。 LL H [MAXN]、X [MAXX]、DP [ 2 ] [MAXX]。 LLのD; INT のmain(){ int型T、N。 scanf関数(" %d個"、&T)。 一方、(T-- ){ scanf関数(" %Dの%のLLD "、&N、&D)。 以下のために(int型私= 0 ; iがN <; ++ i)は、scanf関数(" %のLLD "、&H [I])。 もし(ABS(H [ 0 ] -h [N- 1 ])>(N- 1)* D){ のprintf(" 不可能の\ n " ); 続け; } INT X_SIZE = 0 。 以下のための(int型 I = 0; 私は、n <; ++ I) のために(int型 K = -n + 1、K <= N- 1 ; ++ K) X [X_SIZE ++] = hの[I] + Kの*はD; ソート(X、X + X_SIZE)。 INT NX =一意の(X、X + X_SIZE) - X。 int型、T = 0 ; 以下のために(int型 i = 0 ; iはNXを<; ++ I){ DP [T] [I] = INF。 もし(X [I] == H [ 0 ])DP [T] [I] = 0 ; } のために(int型 I = 1 ; 私は、n <; ++ I){ int型のk = 0 。 用(INT J = 0 ; J <NX; ++ J){ 一方(K <NX && X [K] <X [J] -d)K ++ 。 一方、(k + 1 <NX && X [K + 1 <= X [J] + D && DP [T] [K + 1 <= DP [T] [K])は、k ++ ; もし(DP [T] [K] == INF)DP [T ^ 1 ] [J] = INF。 他 DP [T ^ 1 ] [J] = DP [T] [K] + ABS(H [I] - X [J])。 } T ^ = 1 ; } のために(int型 i = 0 ; iはNXを<; ++ I) であれば(X [I] == H [N- 1 ])のprintf(" %LLDする\ n " 、DP [T] [I])。 } 戻り 0 。 }