タイトル説明
N * Mマトリックス迷路のサイズを有し、それぞれの迷路は、値(R <10 ^ 9)を有しています。迷路で見つかった小さな猿は、彼が唯一の隣接前方四方上下グリッドに向かうことができ、かつ唯一のグリッドの現在の位置よりも大きな値を入力します。しかし、押すことができる小型の猿のSOSボタンがあり、紙の本のサイズ要件を満たしていない隣接するグリッドへの道を余儀なくされますが、このボタンは唯一のK倍を使用することができ、私はから小型類人猿のこの迷路を聞いて、オプションのスターティンググリッドSOSボタンの助けを借りて、どのように多くの手順取るために?(位置はステップ数に含まれる、すなわち、出発点は、ステップ番号1の立っている開始)。
説明を入力します。
最初の入力ラインN、M、K、N次の行は、各列番号Mは、それぞれ、各格子迷路の値を表します。
1 <= N <= 500
1 <= M <= 500
0 <= K <= 10
入力 3. 3. 1。 1. 3. 3。 2. 4 9 8 9 2。 出力 6 示す 一の実施形態を:( 0,0) - >(0,1) - >(0,0) - >(1,0) - >( 2,0) - >(2,1)
分析
DP の動的プログラミング+ DFS(深さ優先探索)
- DP場合は、直接(DP [I] [J] [K]遠いチャンスI、Jからの距離がk回の代表で開始)が返されたときに[X] [Y] [k]は初期値に等しくありません
- 開始位置はつまり、開始点が1から数歩を立っている、工程数を数え
- 周りに前進4つの方向に向かって隣接するグリッド、現在位置番号= MAX(歩行の最大数は、現在の場所であることができ、隣接する位置+1まで歩くの数)まで歩い
- クロスボーダーの場合、無視して次に進みます
- 唯一のグリッドの現在の位置よりも大きな値を入力してください
- ボタンを押して、本押し込ま紙隣接グリッドサイズ(K-1)の要件を満たしていないが、このボタンは、K回使用することができます
IF(マット[X] [Y] <マット[NX] [NY])DP [X] [Y] [K] = Math.max(DP [X] [Y] [k]は、DFS(NX、NY、 K)+ 1)。 IF(マット[X] [Y]> =マット[NX] [NY] && K> 0)DP [X] [Y] [K] = Math.max(DP [X] [Y] [k]は、DFS (NX、NY、K - 1)+ 1)。
- jは、k倍遠いチャンスIからの距離の代表で始まる単一のDP [I] [J] [k]を返します
- 必要に応じてスターティンググリッドは、SOSボタンの助けを借りて、どのように多くの手順(すべて最大)まで行くことができます
コード
インポートjava.util.Scanner; パブリック クラスメイン{ プライベート 静的 INT DX [] = {0 ,. 1、0、-1}; // まで移動させるとダウン迷路 プライベート 静的 INTのDy [] = {1、0、。 -1、0}; // 迷路の動き上下のための プライベート 静的の 整数 N; // 迷路行 プライベート 静的 INT M; // カラム迷路 プライベート 静的 int型 K; // 「強制することができるエントリブックを満たしません隣接するグリッド「用紙サイズ、必要な数 のパブリック 静的 ボイドメイン(文字列[]引数){ スキャナSC = 新しい新スキャナ(System.in); N = sc.nextInt(); M = sc.nextInt(); K = sc.nextInt(); sc.nextLine(); INT [] [] MAT = 新しい新しい INT [N] [ M]; // 各ビン迷路の値 のために(int型、IはNを<; I = 0をIは++ ){ String []型STR = sc.nextLine()スプリット( "" ) のために(INT J = 0。 J <M、J ++ ){ MAT [I] [J] = Integer.valueOf(STR [J]); } } int型[] [] [] DP = 新しい新しい INT [N] [M] [K + 1]; // DP [I] [J] [K]チャンスからの距離が遠いkの代表的なIで始まる、J のための(INT I = 0; iがn <; I ++は){ ため(INT J = 0; J <M、J ++ ){ ため(INT K = 0; K <= K; K ++ ){ DP [I] [J] [K ] = 1; // 初期化 } } } int型 maxResult = 0 ;
//任意にスターティンググリッドは、緊急通報ボタンの助けを借りて、ステップ数に上る ための(int型 I = 0; iがNを<; I ++は) { 用(INT J = 0; J <M、J ++ ){ DP [I] [J]が[K]は = DFS(I、J、K、DP、MAT); maxResult = Math.max(maxResult、DP [I] [J] [K]); // 最大のすべての結果 } } のSystem.out.println(maxResult); } / ** * DFS -ダイナミックプログラミングDP メモリ検索* *は現在の位置を表す(X、 y)の数まで歩くのK機会始まる * @param X-現在位置(X、Y) * @param y軸の現在位置(X、Y)を * @paramのk個の可能性のあるK * @param DP DP [I] [J] [k]はチャンスI、Jから遠い距離で始まるKを表します * @param各ラビリンスグリッドマットの値 * @return * / パブリック 静的 INT DFS(INT X、INT Y、整数 Kは、値int [] [] [] DPを、int型[] []マット){ / ** DP場合[ X] [Y]は、それが直接返されたとき[k]は初期値に等しくない* / IF(DPは、[X] [Y] [K] = -1!) を返すDP [X] [Y] [K]。 / ** 出発点のための工程数が立っている、すなわち位置カウント歩数を、開始1。* / DP [X] [Y] [K] = 1 ; / * 四方隣接格子進む向かっ* / / **のために現在位置番号= MAX(隣接位置+1の数まで歩いて、現在の位置まで歩いて数)まで歩い* * / (int型 I = 0を、Iは<4; Iは++ ){ int型 NX X + = DX [I]; int型 NY = Y + ; Dyの[I] / ** 次に進み、*無視し、次に、境界を* / IF(NX <0 || NX> N = NY || <|| 0をNY> = M) 続行; / ** グリッド位置の値に現在よりだけ大きい* / IF(MAT [X] [Y] < MAT [NX] [NY]) DP [X] [Y] [K ] = Math.max(DP [X] [Y] [K]、DFS(NX、NY、K、DP、MAT)+ 1 ); / ** サイズ要件ブックを満たしていない紙に強制的にボタンを押すことにより隣接する格子(K-1)が、このボタンは、K回使用することができます* / IF (MAT [X] [Y]> = MAT [NX]を[NY] && K> 0) DP [X] [Y] [K] = Math.max - + 1(DP [X] [Y] [K]、DFS(NX、NY、K 1、DP、MAT。)。); } / ** 偶然Kまで徒歩数だけ現在の位置(x、y)からの代表的な* / 戻りDP [X] [Y] [K]; } }