:ゲームプレイがあるようですがある
のn * n個のグリッド、各グリッドは番号を持ちます。
次の規則が適用されます。
- 各プレイヤーが線形ホスト格子によって四の方向に移動させることができ、各移動の距離がmを超えてはなりません
- プレイヤーは、最初の行の最初の列で開始し、グリッドのスコアを受け取りました
- 各プレイヤーは、グリッドに移動するには、スコアを受け取ります
- プレイヤーは、プレイヤーがビッグスコアにしたい現在のセルよりも移動するグリッド値に到着します。
- すべてのゲーム数は、すべての保証を大量にアップ追加しないとこれ以上のint型の整数よりもしていません
- プレイヤーは、境界不正な操作を超えて、唯一のn * n個のグリッド内のグリッドを移動することができます
- プレイヤーは再び移動することはできません場合は、ゲームオーバーされた
今、あなたを求める、最大のスコアを取得することができますプレイヤーはどのくらいですか?
入力
テストデータのセットの複数の
試験サンプルは、2つの整数のそれぞれの最初のラインであるN、M(1≤n≤100)(1≤m≤100 )、 nおよびmは、プログラム終了フラグである-1、出口へ
n個のデジタル記載のn×n個のグリッドの数のn行後の
出力
テストデータ出力ラインの各セットのためには、この行が取得できプレイヤーの最高のスコアを表す唯一の整数であり、
サンプルを入力する
。3 1
。1 5 2
10 11 6
12 12である。7
-1 -1
サンプル出力
37 [
説明
各点4があるため、問題は非常に良いDFSダイレクトバーストサーチではありません移動するための方法を見つけるために、K。
どちらのDPを考え、その後、DFSは、サブ状態値を取得すると思います。どちらか最初に考えたのDFSの後、DPメモリ検索で、直接使用する値DPを通じて、検索処理の重複を減らします。どちらのアイデアは、わずかに異なる解決策は同じもののようですです。
DP [X] [Y]は(この点の(x、y)の値を含む)エネルギーのうち、最大値の規則に従って(x、y)の点を表します。
転送方程式DP [X] [Y] = MAX(DP [DX] [のDy])+迷路[X] [Y];
DX、Dyの4×4つの方向 k個のDPの[DX] [DY]、を表しますルールによってダウンする(DX、DY)の最大値を選択追加最大値自体の(x、y)は、誘導されたDP [X] [Y]はです。
そして、どのように、xのk個のサブ状態の4つの*値、DFS(DX、DY)により得られたYの状態を得るために、被験者の所定の迷路[DX] [DY]>ので迷路[X] [Y] 防止されるDFS単一歩行パスは、彼らが回復VIS別のパスを取ることはありませんとき、VIS配列を開けないでください、重複しています。また、検索のメモリDPアレイにおいて役割を果たし、DP [X] [Y]廃止模索されている、DFS(x、y)の値を直接返すことができる(長い歩行経路、基本セットアップとして制約に従うこと)。
#include <cstdio>
#include <algorithm>
#include <cstring>
int const maxn = 101;
using namespace std;
int dis[][2] ={{1,0},{-1,0},{0,1},{0,-1}};
int dp[maxn][maxn];
int maze[maxn][maxn];
int k , n;
int dfs(int x, int y){
int mx = 0, i, j;
int dx, dy;
if(!dp[x][y]){
for(i = 0; i < 4; i++)
for(j = 1; j <= k; j++){
dx = x + j * dis[i][0];
dy = y + j * dis[i][1];
if(dx >= 0 && dx < n && dy >= 0 && dy < n && maze[dx][dy] > maze[x][y]){
mx = max(mx, dfs(dx, dy));
}
}
dp[x][y] = mx + maze[x][y];
}
return dp[x][y];
}
int main(){
int i, j;
while(~scanf("%d %d", &n, &k)&&(n!= -1 || k!= -1)){
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &maze[i][j]);
memset(dp, 0, sizeof(dp));
int ans = dfs(0, 0);
printf("%d\n", ans);
}
return 0;
}