- 出界的路径数
给你一个大小为 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
题解
动态规划,初始化位置移动0步的方案数为1,然后不断遍历,那么移动i步就是从移动i-1步的状态上得到的方案数,这样就很简单了,最后的答案,再判断移动1步出界数目,移动2步出界数目,,,,,。
AC代码
class Solution {
public:
typedef long long ll;
ll dp[55][55][55];
int xx[4]={0,0,-1,1};
int yy[4]={-1,1,0,0};
ll mod = 1000000007;
int findPaths(int m, int n, int maxMove, int startRow, int startColumn)
{
memset(dp,0,sizeof(dp));
startRow ++;
startColumn ++;
dp[startRow][startColumn][0] = 1;//初始化
for(int i=1;i<=maxMove;i++)
{
for(int j=0;j<=m+1;j++)
{
for(int k=0;k<=n+1;k++)
{
for(int index = 0;index<4;index++)
{
int x = j + xx[index];
int y = k + yy[index];
if(x<=0||x>m||y<=0||y>n)continue;//注意边界判断,只能在网格范围内传递状态数目
dp[j][k][i] += dp[x][y][i-1];//累加上一步可以到达的状态数目
dp[j][k][i] %= mod;
}
}
}
}
ll res = 0;
for(int i=1;i<=maxMove;i++)
{
for(int j=1;j<=m;j++)
{
res += dp[j][0][i];//累加走了i步恰好出界的数目
res += dp[j][n+1][i];
}
for(int j=1;j<=n;j++)
{
res += dp[0][j][i];
res += dp[m+1][j][i];
}
res %= mod;
}
return res;
}
};