给你一个大小为 m x n 的网格和一个球。球的起始坐标为 [startRow, startColumn] 。你可以将球移到在四个方向上相邻的单元格内(可以穿过网格边界到达网格之外)。你 最多 可以移动 maxMove 次球。
给你五个整数 m、n、maxMove、startRow 以及 startColumn ,找出并返回可以将球移出边界的路径数量。因为答案可能非常大,返回对 109 + 7 取余 后的结果。
示例 1:
输入:m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0
输出:6
示例 2:
输入:m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1
输出:12
提示:
1 <= m, n <= 50
0 <= maxMove <= 50
0 <= startRow < m
0 <= startColumn < n
题解如下:
#include<iostream>
#include<vector>
using namespace std;
/*
* 如果 long long dp[51][51][51]; //记忆数组,i:maxMove, j:startRow, k:startColumn
* 用一个三维数组来记忆搜索,如果
* 剩下得移动次确定,当前得坐标确定
* 那么接下来得值一定确定,所以每次到
* 达此情况,记录一次最终路径数,可规避
* 此重复计算次数。
*/
class Solution {
public:
int findPaths(int m, int n, int maxMove, int startRow, int startColumn) {
vector<vector<int>> grid(m, vector<int>(n, 0));
memset(dp, -1, sizeof(dp));
return backtrace(grid, maxMove, startRow, startColumn);
}
/* 返回最终的数 */
long long backtrace(vector<vector<int>>& grid,
int maxMove,
int startRow,
int startColumn) {
// 不满足条件
if (maxMove < 0) {
return 0;
}
if (startRow < 0
|| startColumn < 0
|| startRow >= grid.size()
|| startColumn >= grid[startRow].size()) {
return 1;
}
// 如果小球不管怎么移动都无法越出网格,那就抛弃
if (startRow - maxMove >= 0
&& startColumn - maxMove >= 0
&& startRow + maxMove < grid.size()
&& startColumn + maxMove < grid[startRow].size()) {
return 0;
}
//已经算过不用再算
if (dp[maxMove][startRow][startColumn] > 0) {
return dp[maxMove][startRow][startColumn];
}
dp[maxMove][startRow][startColumn] = (
backtrace(grid, maxMove - 1, startRow + 1, startColumn) +
backtrace(grid, maxMove - 1, startRow - 1, startColumn) +
backtrace(grid, maxMove - 1, startRow, startColumn + 1) +
backtrace(grid, maxMove - 1, startRow, startColumn - 1)
) % M;
return dp[maxMove][startRow][startColumn];
}
private:
long long dp[51][51][51]; //记忆数组,i:maxMove, j:startRow, k:startColumn
const int M = 1e9 + 7;
};
int main() {
Solution* ps = new Solution();
//cout << ps->findPaths(1, 3, 3, 0, 1) << endl;
//cout << ps->findPaths(2, 2, 2, 0, 0) << endl;
//cout << ps->findPaths(36, 5, 50, 15, 3) << endl;
cout << ps->findPaths(45, 35, 47, 20, 31) << endl;
system("pause");
return 0;
}