给你一个下标从 0 开始的 m x n
整数矩阵 grid
和一个整数 k
。你从起点 (0, 0)
出发,每一步只能往 下 或者往 右 ,你想要到达终点 (m - 1, n - 1)
。
请你返回路径和能被 k
整除的路径数目,由于答案可能很大,返回答案对 109 + 7
取余 的结果。
示例 1:
输入:grid = [[5,2,4],[3,0,5],[0,7,2]], k = 3 输出:2 解释:有两条路径满足路径上元素的和能被 k 整除。 第一条路径为上图中用红色标注的路径,和为 5 + 2 + 4 + 5 + 2 = 18 ,能被 3 整除。 第二条路径为上图中用蓝色标注的路径,和为 5 + 3 + 0 + 5 + 2 = 15 ,能被 3 整除。
示例 2:
输入:grid = [[0,0]], k = 5 输出:1 解释:红色标注的路径和为 0 + 0 = 0 ,能被 5 整除。
示例 3:
输入:grid = [[7,3,4,9],[2,3,6,2],[2,3,7,0]], k = 1 输出:10 解释:每个数字都能被 1 整除,所以每一条路径的和都能被 k 整除。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 5 * 104
1 <= m * n <= 5 * 104
0 <= grid[i][j] <= 100
1 <= k <= 50
思路:
状态表示,f [ i ] [ j ] [ x ] 表示走到f [ i ] [ j ] 这个格子余数是k的路径有多少。
状态转移:两种,从上往下走或从左往右走。
代码:
class Solution {
public:
int numberOfPaths(vector<vector<int>>& g, int k) {
int n = g.size(), m = g[0].size(), MOD = 1e9 + 7;
vector<vector<vector<int>>> f(n + 1, vector<vector<int>>(m + 1, vector<int>(k)));
f[1][1][g[0][0] % k] = 1;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ ) {
if (i == 1 && j == 1) continue;
for (int r = 0; r < k; r ++ )
f[i][j][(r + g[i - 1][j - 1]) % k] = (f[i - 1][j][r] + f[i][j - 1][r]) % MOD;
}
return f[n][m][0];
}
};