力扣刷题之3148.矩阵的最大得分

题干描述

给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格(不必相邻)。从值为 c1 的单元格移动到值为 c2 的单元格的得分为 c2 - c1

你可以从任一 单元格开始,并且必须至少移动一次。

返回你能得到的 最大总得分。

示例 1:

**输入:**grid = [[9,5,7,3],[8,9,6,1],[6,7,14,3],[2,5,3,1]]

**输出:**9

解释: 从单元格 (0, 1) 开始,并执行以下移动:

  • 从单元格 (0, 1) 移动到 (2, 1),得分为 7 - 5 = 2

  • 从单元格 (2, 1) 移动到 (2, 2),得分为 14 - 7 = 7

总得分为 2 + 7 = 9

示例 2:

**输入:**grid = [[4,3,2],[3,2,1]]

输出:-1

解释: 从单元格 (0, 0) 开始,执行一次移动:从 (0, 0)(0, 1) 。得分为 3 - 4 = -1

题干分析

题干概述

你有一个正整数组成的矩阵grid,矩阵的大小mXn。你的任务是从矩阵的任意一个单元格开始移动,并且你只能往正下方或者正右侧移动。每次移动的得分是你到达的新单元格的值减去你原来所在单元格的值。你必须至少移动一次,然后计算你可以得到的最大总得分。

主要规则

1.移动方向
  • 你只能向右或者向下移动,也就是说,从一个位置到下一个位置必须在同一行或者同一列,且在同一行时必须往右,在同一列时必须往下。
2.得分计算
  • 每次移动的得分是从当前单元格的值c1到新单元格的值c2的差值,即c2 - c1。
3.起点和终点
  • 你可以从任意单元格开始,并且必须至少移动一次。
4.目标
  • 找到从某个起点开始,经过一系列合法移动之后,得到的最大总得分。

解题思路

1.定义状态
  • 用dp[i][j]表示从单元格(i,j)开始能够获得的最大总得分。
2.初始化
  • dp数组初始化为一个和grid大小相同的二维数组,初始值设置为负无穷大(INT_MIN),表示尚未计算过。
3.状态转移
  • dp[i][j]可以从以下两种情况种选择
  • 从下方单元格(i+1,j)移动到(i,j),此时得分为grid[i][j] - grid[i+1][j] + dp[i+1][j].
  • 从右侧单元格(i,j+1)移动到(i, j),此时得分为grid[i][j] - grid[i][j+1] + dp[i][j+1].
  • 最终,dp[i][j]为上述两种选择中的最大值。
4.求解最终答案
  • 遍历整个dp数组,找到其中的最大值,即为所求的最大总得分。

代码实现

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

// 返回最大得分
int maxScore(int** grid, int gridSize, int* gridColSize) {
    int m = gridSize;
    int n = gridColSize[0];
    int dp[m][n];

    // 初始化dp数组
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            dp[i][j] = INT_MIN; // 初始值设为负无穷大
        }
    }

    int maxScore = INT_MIN;

    // 从右下到左上遍历
    for (int i = m - 1; i >= 0; i--) {
        for (int j = n - 1; j >= 0; j--) {
            // 当前单元格可以从右侧或下方转移过来
            if (i < m - 1) {
                dp[i][j] = grid[i + 1][j] - grid[i][j] + dp[i + 1][j];
            }
            if (j < n - 1) {
                dp[i][j] = grid[i][j + 1] - grid[i][j] + dp[i][j + 1];
            }

            // 如果dp[i][j]还是负无穷大,说明从该点开始没有合理的路径,所以不更新它

            // 更新最大得分
            if (i < m - 1 || j < n - 1) {
                maxScore = max(maxScore, dp[i][j]);
            }
        }
    }

    return maxScore;
}

// 主函数,用于测试
int main() {
    int grid1[4][4] = {
        {9, 5, 7, 3},
        {8, 9, 6, 1},
        {6, 7, 14, 3},
        {2, 5, 3, 1}
    };
    int grid2[2][3] = {
        {4, 3, 2},
        {3, 2, 1}
    };

    int* gridPointers1[4];
    int* gridPointers2[2];
    for (int i = 0; i < 4; i++) {
        gridPointers1[i] = grid1[i];
    }
    for (int i = 0; i < 2; i++) {
        gridPointers2[i] = grid2[i];
    }

    int gridColSize1[1] = {4};
    int gridColSize2[1] = {3};

    printf("Max score for grid1: %d\n", maxScore(gridPointers1, 4, gridColSize1));
    printf("Max score for grid2: %d\n", maxScore(gridPointers2, 2, gridColSize2));

    return 0;
}
相关推荐
小猪咪piggy15 分钟前
【算法】day2 双指针+滑动窗口
数据结构·算法·leetcode
max50060026 分钟前
OpenSTL PredRNNv2 模型复现与自定义数据集训练
开发语言·人工智能·python·深度学习·算法
budingxiaomoli41 分钟前
AVL树知识总结
数据结构·算法
jz-炸芯片的zero1 小时前
【Zephyr电源与功耗专题】14_BMS电池管理算法(三重验证机制实现高精度电量估算)
单片机·物联网·算法·zephyr·bms电源管理算法
u0104058363 小时前
京东返利app的分布式ID生成策略:雪花算法在订单系统中的实践
分布式·算法
小狮子安度因3 小时前
ffplay数据结构分析
数据结构·ffmpeg
lingran__4 小时前
速通ACM省铜第三天 赋源码(Double Perspective和Trip Shopping和Hamiiid, Haaamid... Hamid?)
c++·算法
凤城老人4 小时前
C++使用拉玛努金公式计算π的值
开发语言·c++·算法
时空无限6 小时前
说说transformer 中的掩码矩阵以及为什么能掩盖住词语
人工智能·矩阵·transformer
纪元A梦7 小时前
贪心算法应用:配送路径优化问题详解
算法·贪心算法