リンク:https://ac.nowcoder.com/acm/problem/16496
出典:牛オフネットワーク
タイトル説明
問題を単純化するために、我々は単純化され、ゲームのルールに適応されています:
1.ゲームのインターフェイスは、二次元平面の長さ(管の幅を無視して)k個のパイプがあり、前記N、Mの高さ、です。
2.鳥は常にゲームのインターフェイスに移動します。左端の任意の整数の高さのゲームのインターフェイスからの鳥は、ゲーム画面の右端に到達し、ゲームが終了しています。
右方向の横軸に沿った単位時間当たり3鳥は1、プレイヤによって制御される上下方向の移動距離として定義されます。あなたは、画面上でクリックすると、鳥が一定の高さXを上昇する、あなたは時間の単位ごとに複数回クリックすることができ、効果が重畳され、あなたが画面上でクリックしないと、鳥は一定の高さYをドロップします 場合Yの高さXの高さを昇降方向横軸の異なる位置に鳥は、互いに異なっていてもよいです。
パイプに直面したとき、または、ゲームが失敗0に等しい4鳥鳥高さ。鳥の高さはメートルで、再び上昇することはできません。
さて、あなたはこのゲームを終了するかどうかを判断することができます。あなたが出力クリックの最小数をスクリーニングすることができる場合は、そうでない場合は、隙間から鳥のパイプラインの最大数の出力。
説明を入力します。
;最初の行は、スペースで区切られた各二つの整数の間に3つの整数N、M、K、番号の長さを示し、水ゲームインターフェースの高さ、有する
次のn行、2とのそれぞれの行をスペースで区切られた整数XとYは、プレイヤーは画面をクリックし、それぞれのために、鳥は高さXの次の位置に上げ、そしてプレイヤーが0の横軸の位置に、この位置では、画面上の下の鳥をクリックしない〜N-1高さ下降位置Y.
スペースで区切られた各二つの整数の間に3つの整数P、L、Hの次のk行、。各行はHスリットパイプの上端の高さ(Pは、入力データが異なっていることを確認を表し、横軸はパイプPは、Lは、このパイプの下端が高さLをスリットで表したパイプを表し、大きさの順に保証はありませんアウト)。
出力説明:
あなたがそうでなければ成功したゲーム、出力1、出力0を完了することができた場合、最初の行は、整数が含まれています。
最初の行は、ゲームが正常に完了の出力が他のクリックの最小数の画面、パイプラインを介して鳥類出力ギャップの最大数を必要とし、1であれば2行目は、整数を含んでいます。
例1
輸出
コピー1 6は、
(ナップザックは、第1の状態のDPを定義するときにバックパックが完全にドロップされたとき、それは、これはバックパックの問題だと思うのは簡単です、鳥が上昇[i] [j]が到達点であるタイトルを見てI、クリック数の最小数のJ)立ち上がり時間DPように[I] [J] =分(DP [I]、[J]、DP [I] [JXは[I-1]] + 1)
時間を減少させますDP [I] [J] =分(DP [I]、[J]、DP [I-1] [JY [I-1]) 、我々は問題を見つけることができる:DPの状態を転送[ I] [JX [I-1 ]] の点は、(i-1、I、JXの[ので、到達しないかもしれない ]) カラムが塞がれているので、我々はポイントが列ではないと仮定することができ、最終的に不正な点が無制限割り当て十分な大きさ。
#include <ビット/ STDC ++ H> の#define INF 0x3f3f3f3f 名前空間stdを使用。 const int型MAXN = 1E4 + 5。 INT X [MAXN]、Y [MAXN]。 INT H [MAXN]、H1 [MAXN]。 INT DP [10005] [1005]; // DP [I] [J]为到达横坐标为I纵坐标为J的最少点击次数 INTのmain(){ int型N、M、K。 scanf関数( "%D%D%D"、&N、&M、およびK); {ため(iは++; iがn <I = 0 INT) ("%d個の%のD"、およびX [i]は、&Y [i])とscanf関数と、 } ための式(I = 0 int型、iが<= N; iが++){ 時間[I] = 0; H1 [I] = 3000。 } POS、T_H、t_h1 int型。 (I 0 = int型、I <K; iは++){ため のscanf( "%D%D%D"、&POS&T_H、&t_h1)。 H [POS] = T_H。 H1 [POS] = t_h1。 } のmemset(DP、0x3fを、はsizeof(DP))。 I = 1をint型(ため。 {ため(iは++; iがn = <I = 1 INT) のために(int型のJ = 1; J <= Mであり、j ++){ IF(JX [I-1]> 0) DP [I] [J] =分(分(DP [I] [JX [I-1]、DP [I-1] [JX [I-1]])+ 1、DP [I] [J])。 } (INT J = MX [I-1]; J <= Mであり、j ++){ための IF(J> 0) DP [i]は[M] =分(DP [I] [M]、分(DP [I ] [J]、DP [I-1]〜[J])+ 1)。 } のための(int型J = 1; J <= Mであり、j ++){ IF(J + Yの[I-1] <= M)DP [I] [J] =分(DP [I]、[J]、DP [ I-1] [J + Y [I-1]])。 } のための(INT J = 1; J <= Mであり、j ++){ IF(J <= H [I] || J> = H1 [i])とDP [I] [J] = INF。 } } int型ANS = INF。 以下のために(INT I = 1; I <= M; iは++){ ANS =分(ANS、DP [n]は[I])。 } 場合(ANS = INF!) のprintf( "1 \ n%Dを\ n"、ANS)。 他の{ のprintf(」 int型ANS1 = 0; {(; iがN <I ++は、I = 1 INT)のための {(hは[I] = 0 || H1 [I] = 3000!)場合 (INT J = 1; J <= Mであり、j ++)のために{ 場合(DP [I] [J] = INF!){ ANS1 ++。 ブレーク; } } } } のprintf( "%d個の\ n"、ANS1)。 } 0を返します。 }