E.Easyクライム
どこか近所で我々は、周辺地域の素晴らしい眺めを与える非常に素晴らしい山を持っています。この山に登ることはのでかなり大規模な高さの違いにより、非常に困難である。しかし一つの問題があります。山を登ると景色を楽しむことができ、より多くの人々を作るために、我々は登山を容易にしたいと思います。
次のようにこれを行うには、私たちは山をモデル化します:山は石のn個の隣接するスタックで構成され、各スタックは高いハイテクです。連続した高さの差は、したがって、HI + 1-HI(1≤ためのiがn-1以下)です。我々は、これらの高低差のすべての絶対値よりも小さいか、いくつかの数dに等しくなるようにしたいと思います。
私たちは、スタックの一部の高さを増加または減少させることによってこれを行うことができます。彼らが最初であるように、第1のスタック(出発点)と最後のスタック(終点)は、同じ高さのままでなければなりません。追加や石の除去は多くの労力を必要とするので、我々は追加の石の数の合計取り除か石の合計数を最小限にしたいと思います。この最小数は何ですか?
入力
最初のライン上の一つの正の数:テストケースの数、テストケース当たりその後せいぜい100:
二つの整数N(100≤2≤n)及びD(≤D≤109 0)の一つの行:の積層数石や最大許容高低差。
スタックの高さ:nは整数HI(109≤HI≤0)との一行。
出力
テストケースごとに:
追加または削除するか、目標を達成することは不可能であれば、「不可能」する必要がある石の最小数と一行。
サンプル入力
3
10 2
4 5 10 6 6 9 4 7 8 9
3 1
6 4 0
4 2
3 0 6 3
サンプル出力
6
不可能
4
2008 ACM北西ヨーロッパのプログラミングコンテスト
問題の意味:高度に与えられたNスタック、<= Dの隣接する2つのキュー番号との差が、最小コストを見つけるように、スタックの高さ要件は、エンド・ツー・エンドを変更することができない、変更
ソリューション:
データが小さい場合、まず、その後範囲を直接定義することができるDP [i] [j]は、i番目の最終的な高さは、最小コストの高さb [J]で前処理を意味します。このような状態が定義されている正確には明らかです。
しかし、ここでD 10 ^ 9の範囲は、明らかに私たちは、このような暴力は、それぞれの状態を列挙することはできませんです。
だから、剪定する必要があります。唯一の100の最大の高さを認められたが、1E9の範囲内分布は、
1離散狭い使用して考える必要があり、確かに国家の多くは使用されません。
H1、H2、H3:まず、3つの値の場合のみを考えます。次に、質問の意味は、範囲H2は、間隔[H1-D、H1 + D]、および[H3-D、H 3 + D]交差点、すなわちH1べき[MAX(H1、H3)-d、分(H1であるべきです]の間、H3)+ D。この間隔は空集合である場合、即ち、ABS(H3-H1)>(3-1)* Dは、自然に解決策ない、または:
1、それは範囲H2内にある場合、無修飾;
次に2、H2 <MAX(H1、H3)が-d場合、間隔の最大値(H1、H3)の下限の交点を変更するには、-d。
図3は、H2>分(H1、H3)+ Dの場合、交点が上限分間隔(H1、H3)+ Dを変更しました。
これは、この単純な質問、H2最適な修正のみ3例で見つけることができます。そして、我々はまた、あなたが変更したい場合は、ことが判明非常にHP + K * dの形式でなければなりません変更します。---個別の狭い範囲
それの個別の狭い範囲の後、
考えるには、次の必要性は、状態遷移方程式です。
DP [I] [J] =分(DP [I-1]を[K])+ ABS(X [J] -h [I]); // JD <= K <= J + D。
ときにキューが単調単調一般的なキューは、[]配列は、使用するBに直接ヘッドおよびテールポインタ単調両者を維持するために、単調キューを完了するための唯一の共通書き込みヘッドポインタ、この問題を持っている
第一
具体的に:
まず、ウィンドウのメンテナンスの左端、<B [j]の場合BK]、インデックスkはウィンドウを超えることはできません - D K ++、次いで(bは小から大規模アレイにあるので、ソートされた)、および右の境界から逸脱することなくその後、B [J] + D構内、DP [i]は[K + 1 <= DP [i]は[K]であれば、K ++。
なぜそれが右でありますか?などプライオリティキューが同じああではないの前に言いました!実際には、同じ操作、維持管理は慎重にどのように優先順位キュー操作リコール:フロント二つのポインタ、一度フロント++を超えて、国境の範囲を超えて現在位置を防ぐために、最初の更新の後左の境界を、次にたびに新しい値がミックスに追加します新しい値は、しかし、その後、rear--、新しい値未満になるまで、あなたのキューのうち不要な要素は、新しい値が追加されるよりも大きい場合は、右端のキューの新しい値で現在の要素の大きさを見てと実際にはトップというメソッドポインタは全く同じであり、このステップは、k個の更新時に、ある最小化上に配置され、不要な値を削除します。
#include <iostreamの> する#include <アルゴリズム> の#include <math.h>の に#define LLロングロング の#define MX 999999999999 使用 名前空間STD; LL A [ 205 ]、B [ 1000005 ]、DP [ 205 ] [ 1000005 ]; / / 最小コストのDP最後I山がB [j]の前に完了することが後に[I] [J]は山の高さを表し、 INT のmain() { int型T; CIN >> T; 一方(T-- ) { int型のn、D; CIN >> N- D; のため(int型= I 0、I <N - 、I ++ ) CIN >> A [I]; IF(ABS([N- 1 ] -a [ 0 ])>(N- 1)* D) { COUT << " 不可" << ENDLは、 続行; } LL CNT = 0 ; のため(int型 I = 0、I <N - 、Iは++)// 離散プロセスが配列bのすべての可能な存在山の値を変更します { ため(INT J = 0; J <nであり、j ++ ) { B [CNTが ++] [I] + J *は= Dと、 B [CNTは ++] [i]は-j * = と、d } } int型M。 ソート(B、B + CNT)。 M =一意(B、B + CNT) - B。 以下のために(int型 i = 0 ; iがmを<; I ++)// 初始化DP { DP [ 0 ] [i]は= MX。 もし(B [I] == A [ 0 ]) DP [ 0 ] [I] = 0 ; } 用(INT I = 1 ; I <N-I ++ ) { int型 K = 0 ; // 単調待ち行列先頭ポインタ のための(INT J = 0 ; J <M J ++)// ピークの高さをbに変更する場合は[K ]、その後、B [範囲のK] [B [J] -d、B [J] + D]、 および最適な達成するために、またはBに変更[K] -d、またはbの変化[K] + D { 一方(K <M && B [K] <Bは[J] -d)// 低い値間隔B [j]に変更-d; B [K]> = B [見つける J] -d 出口 K ++ 、 しばらく(K + 1 <M && B [K + 1 <= B [J] && + D DP [I- 1 ] [K + 1 ] <DP = [I- 1 ] [K])// 改变为区间上界值B [J] + Dの K ++ 。 もし(DP [I- 1 ] [K] == MX) DP [I] [J] = MX。 他 DP [I] [j]は DPを= [I- 1 ] [K] + ABS(B [J] - [I])。 } } のために(int型 i = 0 ; iがmを<; iは++ ) { 場合(B [I] == A [N- 1 ]) COUT << DP [N- 1 ] [I] << ENDLと、 } } }