题目描述:
给你一个大小为m*n的网格和一个球。球的起始坐标位[StartRow,startColumn]。你可以将球移到在四个方向上相邻的单元格内(可以穿过网格边界到达网格之外)。你最多可以移动maxMove次球。
给你五个整数m、n、maxMove、startRow以及startColumn,找出并返回可以将球移出边界的路径数量。因为答案可能非常大,返回对10^9+7取余后的结果。
代码思路:
定义dp三维数组dp[i][j][k]代表:从起点开始走路k步到达[i][j]位置,之后用剩余步数能出界的方案个数。
返回条件:
- 步数超限,返回0,即此方案不能在规定步数内越界。if(s > _maxMove) return 0;
- 越界,返回1,即此方案在规定步数内越界,为一种方案。 if(x<0 || x>_m || y<0 || y>_n) return 1;
- dp数组已记录(未记录用-1表示),直接返回记录过的方案个数。if(dp[x][y][s] != -1) return dp[x][y][s];
- 都不满足以上条件,调用四次dfs函数,分别对应上下左右四个方向前进,将返回的方案个数相加,记录并返回。return dp[x][y][s] = (dfs(x+1,y,s+1)+dfs(x-1,y,s+1)+dfs(x,y+1,s+1)+dfs(x,y-1,s+1))%MOD;
代码实现
class Solution {
public:
const int MOD = 1000000007;
long dp[51][51][51];
int _m,_n,_maxMove;
inline long dfs(int x,int y,int s){
if(s > _maxMove)return 0;
if(x<0 || x>=_m || y<0 || y>=_n)return 1;
if(dp[x][y][s] != -1)return dp[x][y][s];
return dp[x][y][s] = (dfs(x+1,y,s+1)+dfs(x-1,y,s+1)+dfs(x,y+1,s+1)+dfs(x,y-1,s+1))%MOD;
}
int findPaths(int m, int n, int maxMove, int startRow, int startColumn) {
memset(dp,-1,sizeof(dp));
_m = m;
_n = n;
_maxMove = maxMove;
return dfs(startRow,startColumn,0);
}
};