力扣刷题之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;
}
相关推荐
CoovallyAIHub5 分钟前
基于YOLOv10-MHSA的“三北”工程内蒙古地区植树位点精准检测研究
深度学习·算法·计算机视觉
晨非辰1 小时前
#C语言——刷题攻略:牛客编程入门训练(八):分支控制(二)
c语言·开发语言·经验分享·学习·其他·学习方法·visual studio
云和数据.ChenGuang2 小时前
Raft协议 一种专为分布式系统设计的共识算法
运维·服务器·算法·区块链·共识算法
用户6120414922132 小时前
C语言做的电子时钟带闹钟带倒计时
c语言·后端·敏捷开发
重生之我是Java开发战士3 小时前
【数据结构】深入理解顺序表与通讯录项目的实现
数据结构·算法
anlogic3 小时前
Java基础 8.11
java·开发语言·算法
sjh21005 小时前
STM32的计数模式和pwm模式
java·stm32·算法
火丁不是灯8 小时前
《 C Primer Plus》
c语言·开发语言
dlraba80211 小时前
机器学习-----K-means算法介绍
算法·机器学习·kmeans
芥子须弥Office12 小时前
从C++0基础到C++入门 (第二十五节:指针【所占内存空间】)
c语言·开发语言·c++·笔记