力扣刷题之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;
}
相关推荐
hie988948 分钟前
基于matlab策略迭代和值迭代法的动态规划
算法·动态规划
Coovally AI模型快速验证10 分钟前
SFTrack:面向警务无人机的自适应多目标跟踪算法——突破小尺度高速运动目标的追踪瓶颈
人工智能·神经网络·算法·yolo·计算机视觉·目标跟踪·无人机
Brduino脑机接口技术答疑11 分钟前
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
人工智能·算法·脑机接口·新手入门
真的很上进22 分钟前
2025最全TS手写题之partial/Omit/Pick/Exclude/Readonly/Required
java·前端·vue.js·python·算法·react·html5
linweidong28 分钟前
GO 基础语法和数据类型面试题及参考答案(下)
算法·后端面试·泛型·go面试·go面经·go求职
圈圈编码1 小时前
LeetCode Hot100刷题——合并两个有序链表
java·数据结构·算法·leetcode·链表
岁忧1 小时前
LeetCode 高频 SQL 50 题(基础版)之 【高级字符串函数 / 正则表达式 / 子句】· 下
sql·leetcode·正则表达式
啊我不会诶1 小时前
篮球杯软件赛国赛C/C++ 大学 B 组补题
c语言·c++
老歌老听老掉牙2 小时前
旋量理论:刚体运动的几何描述与机器人应用
python·算法·机器学习·机器人·旋量
无聊的小坏坏2 小时前
用递归算法解锁「子集」问题 —— LeetCode 78题解析
算法·深度优先