use std::collections::HashMap; const CAP: i64 = 1000000007; struct DPSolver { m: i32, n: i32, max_move: i32, dp: Vec>, } impl DPSolver { pub fn new(m: i32, n: i32, max_move: i32) -> Self { let dp = vec![HashMap::new(); (m as usize) * (n as usize)]; Self { m, n, max_move, dp } } fn index(&self, y: i32, x: i32) -> usize { (y * self.n + x) as usize } fn dfs(&mut self, y: i32, x: i32, moves: i32) -> i64 { if y < 0 || y >= self.m || x < 0 || x >= self.n { // BASE: we got out of the bounds return 1; } if moves <= 0 { // BASE: all moves were used or there are no moves left return 0; } let idx = self.index(y, x); if let Some(paths) = self.dp[idx].get(&moves) { return *paths; } let mut options = 0; for (dx, dy) in [(0, 1), (1, 0), (0, -1), (-1, 0)] { options = (options + self.dfs(y + dy, x + dx, moves - 1)) % CAP; } self.dp[idx].insert(moves, options); options } pub fn get(&mut self, y0: i32, x0: i32) -> i32 { self.dfs(y0, x0, self.max_move) as i32 } } struct Solution {} impl Solution { pub fn find_paths(m: i32, n: i32, max_move: i32, start_row: i32, start_column: i32) -> i32 { DPSolver::new(m, n, max_move).get(start_row, start_column) } }