前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >2022-06-10:薯队长从北向南穿过一片红薯地(南北长M,东西宽N),红薯地被划分为1x1的方格,他可以从北边的任何一个格子

2022-06-10:薯队长从北向南穿过一片红薯地(南北长M,东西宽N),红薯地被划分为1x1的方格,他可以从北边的任何一个格子

作者头像
福大大架构师每日一题
发布2023-06-08 14:24:04
发布2023-06-08 14:24:04
12000
代码可运行
举报
运行总次数:0
代码可运行

2022-06-10:薯队长从北向南穿过一片红薯地(南北长M,东西宽N),红薯地被划分为1x1的方格,

他可以从北边的任何一个格子出发,到达南边的任何一个格子,

但每一步只能走到东南、正南、西南方向的三个格子之一,

而且不能跨出红薯地,他可以获得经过的格子上的所有红薯,请问他可以获得最多的红薯个数。

来自小红书,小红书第一题。

答案2022-06-10:

动态规划。dp是两行格子。dp[0]是加arr[i][j]之前的最大值数组。dp[1]是加arr[i][j]之后最大值数组。

dp[1][j]=arr[i][j]+max(dp[0][j-1],dp[0][j],dp[[0][j+1])。未来不确定,但是过去是确定的。dp[0]代表过去,dp[1]根据过去的三条方向选择最优方向即可。

时间复杂度:O(MN)。

空间复杂度:O(N)。占用两行格子。

代码用rust编写。代码如下:

代码语言:javascript
代码运行次数:0
复制
fn main() {
    let mut map: Vec<Vec<i32>> = vec![
        vec![3, 5, 6, 2, 4],
        vec![7, 8, 9, 1, 1],
        vec![1, 2, 3, 4, 5],
    ];
    let ans = max_score(&mut map);
    println!("ans = {}", ans);
    let mut map: Vec<Vec<i32>> = vec![
        vec![3, 5, 6, 2, 4],
        vec![7, 8, 9, 1, 1],
        vec![1, 2, 3, 4, 5],
    ];
    let ans = max_score2(&mut map);
    println!("ans = {}", ans);
    let mut map: Vec<Vec<i32>> = vec![
        vec![3, 5, 6, 2, 4],
        vec![7, 8, 9, 1, 1],
        vec![1, 2, 3, 4, 5],
    ];
    let ans = max_score3(&mut map);
    println!("ans = {}", ans);
}

fn max_score(map: &mut Vec<Vec<i32>>) -> i32 {
    let mut ans = 0;
    for col in 0..map[0].len() as i32 {
        ans = get_max(ans, process(map, 0, col));
    }
    return ans;
}

fn process(map: &mut Vec<Vec<i32>>, row: i32, col: i32) -> i32 {
    if col < 0 || col == map[0].len() as i32 {
        return -1;
    }
    if row == map.len() as i32 - 1 {
        return map[row as usize][col as usize];
    }
    let cur = map[row as usize][col as usize];
    let next1 = process(map, row + 1, col - 1);
    let next2 = process(map, row + 1, col);
    let next3 = process(map, row + 1, col + 1);
    return cur + get_max(get_max(next1, next2), next3);
}

fn max_score2(map: &mut Vec<Vec<i32>>) -> i32 {
    let mut ans = 0;
    let n = map.len() as i32;
    let m = map[0].len() as i32;
    let mut dp: Vec<Vec<i32>> = vec![];
    for i in 0..n {
        dp.push(vec![]);
        for _ in 0..m {
            dp[i as usize].push(-2);
        }
    }
    for col in 0..map[0].len() as i32 {
        ans = get_max(ans, process2(map, 0, col, &mut dp));
    }
    return ans;
}

fn process2(map: &mut Vec<Vec<i32>>, row: i32, col: i32, dp: &mut Vec<Vec<i32>>) -> i32 {
    if col < 0 || col == map[0].len() as i32 {
        return -1;
    }
    if dp[row as usize][col as usize] != -2 {
        return dp[row as usize][col as usize];
    }
    // 继续算!
    let mut ans = 0;
    if row == map.len() as i32 - 1 {
        ans = map[row as usize][col as usize];
    } else {
        let cur = map[row as usize][col as usize];
        let next1 = process2(map, row + 1, col - 1, dp);
        let next2 = process2(map, row + 1, col, dp);
        let next3 = process2(map, row + 1, col + 1, dp);
        ans = cur + get_max(get_max(next1, next2), next3);
    }
    dp[row as usize][col as usize] = ans;
    return ans;
}

// 最优方法
fn max_score3(map: &mut Vec<Vec<i32>>) -> i32 {
    let n = map.len() as i32;
    let m = map[0].len() as i32;
    let mut dp: Vec<Vec<i32>> = vec![];
    for _ in 0..2 {
        dp.push(map[0].clone());
    }

    for i in 1..n {
        for j in 0..m as i32 {
            dp[1][j as usize] = get_max(
                get_max(
                    dp[0][j as usize],
                    if j - 1 >= 0 {
                        dp[0][(j - 1) as usize]
                    } else {
                        0
                    },
                ),
                if j + 1 < m {
                    dp[0][(j + 1) as usize]
                } else {
                    0
                },
            ) + map[i as usize][j as usize];
        }
        dp[0] = dp[1].clone();
    }

    let mut ans = dp[0][0];
    for i in 1..m {
        ans = get_max(ans, dp[0][i as usize]);
    }

    return ans;
}

fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
    if a > b {
        a
    } else {
        b
    }
}

执行结果如下:

***

[左神java代码](https://github.com/algorithmzuo/weekly-problems/blob/main/src/class_2022_04_1_week/Code04_MaxScoreMoveInBoard.java)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档