「笔试刷题」:字母收集

22 阅读2分钟

一、题目

描述

有一个 𝑛∗𝑚 的矩形方阵,每个格子上面写了一个小写字母。
小红站在矩形的左上角,她每次可以向右或者向下走,走到某个格子上就可以收集这个格子的字母。
小红非常喜欢 "love" 这四个字母。她拿到一个 l 字母可以得 4 分,拿到一个 o 字母可以得 3 分,拿到一个 v 字母可以得 2 分,拿到一个 e 字母可以得 1 分。
她想知道,在最优的选择一条路径的情况下,她最多能获取多少分?

输入描述:

1≤𝑛,𝑚≤500
接下来的 𝑛n 行 每行一个长度为 𝑚 的、仅有小写字母构成的字符串,代表矩形方阵。

输出描述:

小红最大可能的得分。

示例1

输入:

3 2
ab
cd
ef

输出:

1

说明:

选择下、下、右)这条路径即可,可以收集到 acef 这四个字母各一次,获得 0+0+1+0=1 分。  

示例2

输入:

2 3
lle
ove

复制输出:

11

二、思路解析

这道题我们可以用动态规划的解题思想来做。

通过一个二维数组 dp,来表示: dp[i][j] 即,到达[i,j] 位置的时候,最大的分数是多少。

那通过画图我们可以知道,动态反应方程就是:

dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + t;

​编辑

根据当前格子上的字母,确定当前格子的得分并更新 dp[i][j]。

最终输出 dp[n][m],即最右下角格子处的最大得分。

具体实现请看下面代码👇

三、完整代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        char[][] grid = new char[n + 1][m + 1];

        for(int i = 1; i <= n; i++){
            char[] s = in.next().toCharArray();
            for(int j = 1; j <= m; j++){
                grid[i][j] = s[j - 1];
            }
        }

        int[][] dp = new int[n + 1][m + 1];
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                int t = 0;
                if(grid[i][j] == 'l'){
                    t = 4;
                }else if(grid[i][j] == 'o'){
                    t = 3;
                }else if(grid[i][j] == 'v'){
                    t = 2;
                }else if(grid[i][j] == 'e'){
                    t = 1;
                }

                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + t;
            }
        }
        System.out.println(dp[n][m]);
    }
}

以上就是本篇博客的全部内容啦,如有不足之处,还请各位指出,期待能和各位一起进步!