576範囲外のパスの数
与えられたメッシュとM×N個のボールのために。ボールの初期座標は、あなたは下、左、右方向のメッシュの境界ボールを動かし、上向きのボールに隣接するセルを移動する、またはすることができ、(i、j)があります。ただし、N回まで移動することができます。パスの数は、ボールの境界外に移動することができますして下さい。答えは非常に大きくてもよい、戻り値は、結果MOD 109 + 7です。
例1:
入力:M = 2、N = 2 、N = 2、I = 0、J = 0
出力:6
説明:
例2:
入力:M = 1、N = 3 、N = 3、I = 0、J = 1つの
出力:12
説明:
説明:
範囲外のボールと、それは戻ってグリッドに移動することはできません。
グリッドの長さと高さの範囲[1,50]の。
の範囲[0,50]でN。
PS:
DFSの伝統的な小さな一連の
首長は、動的計画法を作りました
class Solution {
private Integer[][][] cache;
public int findPaths(int m, int n, int N, int i, int j) {
cache = new Integer[m][n][N+1];
return dfs(m,n,N,j,i);
}
private int dfs(int rows,int cols,int times,int x,int y) {
if (isOutOfBoundary(x,y,rows,cols)) {
return 1;
}
if (0 == times) {
return 0;
}
if (null != cache[y][x][times]) {
return cache[y][x][times];
}
int res = (((dfs(rows,cols,times-1,x+1,y) + dfs(rows,cols,times-1,x-1,y)) % 1000000007) + ((dfs(rows,cols,times-1,x,y+1) + dfs(rows,cols,times-1,x,y-1)) % 1000000007)) % 1000000007;
cache[y][x][times] = res;
return res;
}
private boolean isOutOfBoundary(int x,int y,int rows,int cols) {
return x < 0 || x >= cols || y < 0 || y >= rows;
}
}
class Solution {
public int findPaths(int m, int n, int N, int i, int j) {
if(N <= 0) return 0;
int mod = 1000000007;
int ret = 0;
int[][] dp = new int[m][n]; // 保存第k步的结果
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for(int k = 1; k <= N; ++k) {
int[][] temp = new int[m][n]; // 保存第k-1步的结果
for(int x = 0; x < m; ++x) {
for(int y = 0; y < n; ++y) {
for(int[] dir : dirs) {
int nx = x + dir[0];
int ny = y + dir[1];
if(nx < 0 || nx >= m || ny < 0 || ny >= n)
temp[x][y] += 1;
else
temp[x][y] = (dp[nx][ny] + temp[x][y]) % mod;
}
}
}
dp = temp;
}
return dp[i][j];
}
}