当前位置: 首页 > article >正文

【C++动态规划 前缀和】937. 扣分后的最大得分|2105

本文涉及知识点

下载及打开打包代码的方法兼述单元测试
C++动态规划
C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频

LeetCode1937. 扣分后的最大得分

给你一个 m x n 的整数矩阵 points (下标从 0 开始)。一开始你的得分为 0 ,你想最大化从矩阵中得到的分数。

你的得分方式为:每一行 中选取一个格子,选中坐标为 (r, c) 的格子会给你的总得分 增加 points[r][c] 。

然而,相邻行之间被选中的格子如果隔得太远,你会失去一些得分。对于相邻行 r 和 r + 1 (其中 0 <= r < m - 1),选中坐标为 (r, c1) 和 (r + 1, c2) 的格子,你的总得分 减少 abs(c1 - c2) 。

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

abs(x) 定义为:

如果 x >= 0 ,那么值为 x 。
如果 x < 0 ,那么值为 -x 。

示例 1:
在这里插入图片描述

输入:points = [[1,2,3],[1,5,1],[3,1,1]]
输出:9
解释:
蓝色格子是最优方案选中的格子,坐标分别为 (0, 2),(1, 1) 和 (2, 0) 。
你的总得分增加 3 + 5 + 3 = 11 。
但是你的总得分需要扣除 abs(2 - 1) + abs(1 - 0) = 2 。
你的最终得分为 11 - 2 = 9 。
示例 2:
在这里插入图片描述

输入:points = [[1,5],[2,3],[4,2]]
输出:11
解释:
蓝色格子是最优方案选中的格子,坐标分别为 (0, 1),(1, 1) 和 (2, 0) 。
你的总得分增加 5 + 3 + 4 = 12 。
但是你的总得分需要扣除 abs(1 - 1) + abs(1 - 0) = 1 。
你的最终得分为 12 - 1 = 11 。
提示:
m == points.length
n == points[r].length
1 <= m, n <= 105
1 <= m * n <= 105
0 <= points[r][c] <= 105

动态规划+前后缀最大值

动态规划的状态表示

dp[r][c] 表示已经处理了r行,最后一行选择的是第c列的最大得分。空间复杂度:O(nm)

动态规划的填表顺序

枚举后序状态,r = 1 to m
一,枚举右移,c从0到C-1。
二,枚举左移,c从C-1到0。

动态规划的转移方程

右移:
x = max(pre[i]+i) i ∈ \in [0,c] cur[c] = x - c+ points[r][c];
左移:
x = max(pre[i]-i) i ∈ \in [c,C-1] MaxSelf(cur[c],x+c+ points[r][c])
利用前后缀最大值后,单个状态转移的时间复杂度:O(1),总时间复杂度:O(mn)

动态规划的初始值

dp[0]为0,其它为LLON_MIN/2

动态规划的返回值

dp.back的最大值

代码

核心代码

class Solution {
		public:
			long long maxPoints(vector<vector<int>>& points) {
				const int R = points.size();
				const int C = points.front().size();
				vector<long long> pre(C);
				for (int r = 0; r < R; r++) {
					vector<long long> cur(C);
					long long lMax = INT_MIN;
					for (int c = 0; c < C; c++) {
						lMax = max(lMax, pre[c] + c);
						cur[c] = lMax - c+points[r][c];
					}
					lMax = INT_MIN;
					for (int c = C - 1; c >= 0; c--) {
						lMax = max(lMax, pre[c] - c);
						cur[c] = max(cur[c], lMax + c + points[r][c]);
					}
					pre.swap(cur);
				}
				return *max_element(pre.begin(), pre.end());
			}
		};

单元测试

	vector<vector<int>> points;
		TEST_METHOD(TestMethod11)
		{
			points = { {1,2,3},{1,5,1},{3,1,1} };
			auto res = Solution().maxPoints(points);
			AssertEx(9LL, res);
		}
		TEST_METHOD(TestMethod12)
		{
			points = { {1,5},{2,3},{4,2} };
			auto res = Solution().maxPoints(points);
			AssertEx(11LL, res);
		}
		TEST_METHOD(TestMethod13)
		{
			points = { {5,3},{3,5},{3,1} };
			auto res = Solution().maxPoints(points);
			AssertEx(11LL, res);
		}
		TEST_METHOD(TestMethod14)
		{
			points = { {5,8,6,9,2},{3,2,2,6,0},{2,5,6,10,3},{4,2,1,6,0},{7,3,3,7,5},{4,3,3,0,10},{3,6,5,4,1},{4,5,10,8,6},{10,8,5,0,1},{4,2,9,4,0} };
			auto res = Solution().maxPoints(points);
			AssertEx(75LL, res);
		}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。


http://www.kler.cn/a/450658.html

相关文章:

  • C++23新特性解析:[[assume]]属性
  • 【Unity3D】Particle粒子特效或3D物体显示在UGUI上的方案
  • 面向未来的教育技术:智能成绩管理系统的开发
  • 有没有检测吸烟的软件 ai视频检测分析厂区抽烟报警#Python
  • 下载运行Vue开源项目vue-pure-admin
  • Linux -- 线程的优点、pthread 线程库
  • 5、mysql的读写分离
  • 使用QML实现播放器进度条效果
  • spring mvcservlet跳转页面没有样式效果
  • ubuntu安装nginx
  • leetcode之hot100---24两两交换链表中的节点(C++)
  • Ubuntu离线安装Docker容器
  • vscode添加全局宏定义
  • 青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
  • AI如何进行风险控制:深度解析与实战应用
  • 开源模型应用落地-LlamaIndex学习之旅-Agents-用自然语言构建Agent(一)
  • Linux -- 线程的优点、pthread 线程库
  • 南海区2021年C++甲组真题第3题——Excel地址
  • 【C# 联合halcon实现绘制箭头】
  • 【C语言】`free` 函数详细讲解
  • 如何在谷歌浏览器中设置邮件客户端
  • OSError: [Errno 98] Address already in use pycharm 远程
  • 重温设计模式--迭代器模式
  • Python项目之Pygame制作新年烟花!
  • 【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
  • Vue 3 和 Vue Router 使用 createWebHistory 配置