题目要求
有一个m*n的网格,网格中有一个小球。小球初始位置位[startRow,startColumn]。您可以将小球移动到网格中相邻的四个单元格之一(可能会越过网格边界移出网格)。最多可以对小球进行maxMove移动。
给定 m、n、maxMove、startRow、startColumn 这五个整数,返回将小球移出网格边界的路径数。由于答案可能非常大,因此请返回 的模数。
Example 1:
Input: m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0 Output: 6
Example 2:
Input: m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1 Output: 12
思路
这个题目有三个状态:横坐标、纵坐标和可移动的次数,所以我们可以用一个三维的dp数组存储这三个状态或者一个带有三个参数的dp函数。
状态转移关系:在maxMove步之内从(i,j)位置踢出界外的路径数量等于在maxMove-1步之内从(i,j)的相邻位置踢出界外的路径数量之和。(相邻位置多走一步可以到达i,j)
注意处理计算的冗余和基础情况。这里的递归采用的是数组和递归函数相结合的方式。参考labuladong的思路和题解。
代码
class Solution {
public:int memo[50][50][51];int m, n;int findPaths(int m, int n, int maxMove, int startRow, int startColumn) {this->m = m;this->n = n;memset(memo, -1, sizeof(memo));return dp(maxMove, startRow, startColumn);}int dp(int maxMove, int i, int j) {// base case,找到一条出界路径if (i < 0 || j < 0 || i >= m || j >= n) {return 1;}// 避免冗余计算if (memo[i][j][maxMove] != -1) {return memo[i][j][maxMove];}// 无法在有限的步数内出界if (maxMove == 0) {return 0;}// 状态转移关系:// 在maxMove步之内从(i,j)踢出界外的路径数量等于// 在maxMove-1步之内从(i,j)的相邻位置出界的路径数量之和;long res = 0;res += dp(maxMove - 1, i-1, j);res += dp(maxMove - 1, i+1, j);res += dp(maxMove - 1, i, j-1);res += dp(maxMove - 1, i, j+1);memo[i][j][maxMove] = (int)(res % 1000000007);return memo[i][j][maxMove];}
};