题解 | #礼物的最大价值#
礼物的最大价值
https://www.nowcoder.com/practice/2237b401eb9347d282310fc1c3adb134
- 动态规划的总逻辑 res = grid[x][y] + fn(grid[x+1][y]) + fn(grid[x][y+1])
- 存在重复计算的部份,比如 res = grid[0][0] + fn(grid[0][1]) + fn(grid[1][0]) fn(grid[0][1]) 会去计算 grid[0][1] + fn(grid[0][2]) + fn(grid[1][1]) fn(grid[1][0]) 会去计算 grid[1][0] + fn(grid[1][1]) + fn(grid[0,2]) 可以看到fn(grid[1][1]) ,也就是数字5为起点,都会被重复计算,此时只需要算一遍就行。解决办法是将每个节点的为起点的结果,都记录到另一个二维数组中。
- 这里的rust实现,主要存储结果的数组,包裹了option,用于记录有没有计算过结果。----其实不用option也行
- 另外需要注意,对于index的访问,不要越界。处理办法是访问前先判断,对比inde和长度
1 3 1 1 5 1 4 2 1
struct Solution{ } impl Solution { fn new() -> Self { Solution{} } /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param grid int整型二维数组 * @return int整型 */ pub fn maxValue(&self, grid: Vec<Vec<i32>>) -> i32 { // write code here let mut flag: Vec<Vec<Option<i32>>> = vec![vec![None; grid[0].len()]; grid.len()]; self.maxValue_dp(&grid,0,0,&mut flag) } pub fn maxValue_dp(&self,grid:&Vec<Vec<i32>>,x:usize,y:usize,flag:&mut Vec<Vec<Option<i32>>>) -> i32{ // Check if we've already computed this value if let Some(value) = flag[x][y] { return value; } // Base case: reached the bottom-right corner if x == grid.len() - 1 && y == grid[0].len() - 1 { return grid[x][y]; } // Recursive cases: move right or down let right = if x + 1 < grid.len() { self.maxValue_dp(grid, x + 1, y, flag) } else { // std::i32::MIN 0 }; let down = if y + 1 < grid[0].len() { self.maxValue_dp(grid, x, y + 1, flag) } else { // std::i32::MIN 0 }; // Choose the maximum value from moving right or down let max_path_value = grid[x][y] + right.max(down); // Memoize the result flag[x][y] = Some(max_path_value); max_path_value } }#rust#