题解 | #礼物的最大价值#
礼物的最大价值
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#