力扣刷题之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.定义状态
  • 用dpij表示从单元格(i,j)开始能够获得的最大总得分。
2.初始化
  • dp数组初始化为一个和grid大小相同的二维数组,初始值设置为负无穷大(INT_MIN),表示尚未计算过。
3.状态转移
  • dpij可以从以下两种情况种选择
  • 从下方单元格(i+1,j)移动到(i,j),此时得分为gridij - gridi+1j + dpi+1j.
  • 从右侧单元格(i,j+1)移动到(i, j),此时得分为gridij - gridij+1 + dpij+1.
  • 最终,dpij为上述两种选择中的最大值。
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;
}
相关推荐
上海安当技术1 小时前
C/S 桌面软件怎么接 UKey 强认证?C# SDK 与 C 动态库集成 WinForms/Qt/工控实战
c语言·qt·c#
歪歪歪比巴卜2 小时前
服务商批量接手客户跨平台社媒账号的技术落地:体检体系与重启架构
矩阵·架构·aigc
比卡超哥2 小时前
Ctorch开发日志——矩阵乘法优化及数学原理
线性代数·矩阵
(Charon)2 小时前
【C++】锁与原子操作(四):自旋锁的完整实现与性能优化
c语言·开发语言·c++
Ivanqhz2 小时前
php8 use-def链
算法·php
evans在进步3 小时前
LeetCode 189 轮转数组:三次反转原地解决,图解 Java 实现
java·算法·leetcode
歌_顿3 小时前
Drawing_To_Model
算法
龍德明宇3 小时前
AI不会疼-龍德明宇
人工智能·算法·大语言模型llm·负主体性·ai存在论
302wanger3 小时前
程序员写 SOP:把脑子里的流程固化下来
算法
小羊先生car4 小时前
RTOS-F429-HAL-Freertos内存管理(2026/8/5)
c语言·单片机·rtos