C++前缀和算法的应用:石头游戏 VIII 原理源码测试用例

news2025/1/14 19:45:29

本文涉及的基础知识点

C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频

题目

Alice 和 Bob 玩一个游戏,两人轮流操作, Alice 先手 。
总共有 n 个石子排成一行。轮到某个玩家的回合时,如果石子的数目 大于 1 ,他将执行以下操作:
选择一个整数 x > 1 ,并且 移除 最左边的 x 个石子。
将 移除 的石子价值之 和 累加到该玩家的分数中。
将一个 新的石子 放在最左边,且新石子的值为被移除石子值之和。
当只剩下 一个 石子时,游戏结束。
Alice 和 Bob 的 分数之差 为 (Alice 的分数 - Bob 的分数) 。 Alice 的目标是 最大化 分数差,Bob 的目标是 最小化 分数差。
给你一个长度为 n 的整数数组 stones ,其中 stones[i] 是 从左边起 第 i 个石子的价值。请你返回在双方都采用 最优 策略的情况下,Alice 和 Bob 的 分数之差 。
示例 1:
输入:stones = [-1,2,-3,4,-5]
输出:5
解释:

  • Alice 移除最左边的 4 个石子,得分增加 (-1) + 2 + (-3) + 4 = 2 ,并且将一个价值为 2 的石子放在最左边。stones = [2,-5] 。
  • Bob 移除最左边的 2 个石子,得分增加 2 + (-5) = -3 ,并且将一个价值为 -3 的石子放在最左边。stones = [-3] 。
    两者分数之差为 2 - (-3) = 5 。
    示例 2:
    输入:stones = [7,-6,5,10,5,-2,-6]
    输出:13
    解释:
  • Alice 移除所有石子,得分增加 7 + (-6) + 5 + 10 + 5 + (-2) + (-6) = 13 ,并且将一个价值为 13 的石子放在最左边。stones = [13] 。
    两者分数之差为 13 - 0 = 13 。
    示例 3:
    输入:stones = [-10,-12]
    输出:-22
    解释:
  • Alice 只有一种操作,就是移除所有石子。得分增加 (-10) + (-12) = -22 ,并且将一个价值为 -22 的石子放在最左边。stones = [-22] 。
    两者分数之差为 (-22) - 0 = -22 。
    参数范围:
    n == stones.length
    2 <= n <= 105
    -104 <= stones[i] <= 104

分析

思路

dp[i]表示剩余i个石头时,(先手方分数-后手方分数)的最大值。计算dp[i]时,假定移除石头后,还剩j个,也就是总共(包括之前移除)移除m_c-j个。至少移除一个旧石头,故j的取值范围[0,i) 。cur = stones[0,m_c-j)个石头的价值和 - dp[j]。dp[i]等于cur的最大值。

x > 1

初始状态下,只能移除2个,不能移除1个。
非初始状态下,由于必定会移除新石头,所以移除一个旧石头就可以了。
也就是dp[m_c]时m_c-j不能等于1,也就是j不能m_c-1。j无此限制的取值范围是[0,m_c),加上此限制后就变成[0,m_c-1),即i < m_c-1

注意

题意:包括新石头,只剩一个石头的时候结束。我的理解:不包括新石头,没石头的时候结束。初始状态外,一定有新石头,所以两种等价。初始状态,且石头大于1时,两者等价,都是未结束。一个石头,两者不等价。但本题石头数>=2。所以在本题范围内等价。

怀疑

这个题目可能出错了,可能是不放新石头。这样需要技巧合并i。

代码

错误代码

错误原因:忽略了x>1。
class Solution {
public:
int stoneGameVIII(vector& stones) {
m_c = stones.size();
vector dp(m_c + 1);//dp[i]表示剩余i个石头时,(先手方分数-后手方分数)的最大值
//计算dp[i]时,假定移除石头后,还剩j个,也就是移除m_c-j个
// cur = stones[0,m_c-j)个石头的价值和 - dp[j]
vector vSum = { 0 };
for (const auto& n : stones)
{
vSum.emplace_back(n + vSum.back());
}
int iMax = vSum[m_c - 0]-dp[0];
for (int i = 1; i <= m_c; i++)
{
dp[i] = iMax;
iMax = max(iMax, vSum[m_c - i] - dp[i]);
}
return dp.back();
}
int m_c;
};

修正缺陷后

解决方法

class Solution {
public:
	int stoneGameVIII(vector<int>& stones) {
		m_c = stones.size();
		//dp[i]表示剩余i个石头时,(先手方分数-后手方分数)的最大值
		m_dp.resize(m_c + 1);
		//计算dp[i]时,假定移除石头后,还剩j个,也就是移除m_c-j个
		// j的取值范围[0,i) 且m_c-j>1
		// cur = stones[0,m_c-j)个石头的价值和 - dp[j]
		vector<int> vSum = { 0 };
		for (const auto& n : stones)
		{
			vSum.emplace_back(n + vSum.back());
		}
		int iMax = vSum[m_c - 0]-m_dp[0];
		for (int i = 1; i <= m_c; i++)
		{
			m_dp[i] = iMax;
			if (m_c - i > 1)
			{
				iMax = max(iMax, vSum[m_c - i] - m_dp[i]);
			}
		}
		return m_dp.back();
	}
	int m_c;
	vector<int> m_dp;//dp[i]表示剩余i个石头时,(先手方分数-后手方分数)的最大值
};

测试用例

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

int main()
{
Solution slu;
vector stones;
int res = 0;
stones = { -1, 2, -3, 4, -5, 6 };
res = slu.stoneGameVIII(stones);
Assert(3, res);
Assert(vector{0, 3, 3, 3, 3, 3, 3}, slu.m_dp);
stones = { -3,-5,3 };
res = slu.stoneGameVIII(stones);
Assert(-3, res);
Assert(vector{0, -5,-3,-3}, slu.m_dp);
stones = { -1, 2, -3, 4, -5 };
res = slu.stoneGameVIII(stones);
Assert(5, res);
Assert(vector{0, -3, 5, 5, 5, 5}, slu.m_dp);
stones = { -10,-12 };
res = slu.stoneGameVIII(stones);
Assert(-22, res);
Assert(vector{0, -22,-22}, slu.m_dp);

//CConsole::Out(res);

}

2023年2月旧代码

class Solution {
public:
int stoneGameVIII(vector& stones) {
m_c = stones.size();
vector preSum;
int iSum = 0;
for (const auto& s : stones)
{
iSum += s;
preSum.push_back(iSum);
}
vector dp(m_c);
dp.back() = preSum.back();
for (int i = m_c - 2; i >= 1; i–)
{
dp[i] = max(dp[i + 1], preSum[i] - dp[i + 1]);
}
return dp[1];
}
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《闻缺陷则喜算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

| 鄙人想对大家说的话
|
|-|
|闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。|
| 墨家名称的来源:有所得以墨记之。 |
|如果程序是一条龙,那算法就是他的是睛|

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1127556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ACM练习C++知识点笔记

1、字符和数字的转换 #include<iostream> using namespace std; int main(){int n 8 - 48;cout<<n<<endl;return 0; } 数字转字符串 #include <string> #include <sstream> #include <iostream> using namespace std; int main() {doubl…

基于Django开发的推荐系统与数据分析系统

基于Django开发的推荐系统与数据分析系统 一、简介 已开发的的推荐系统&#xff1a;图书管理系统、电影推荐系统、在线选修课程推荐系统、健身推荐系统、资讯推荐系统&#xff1b; 已开发的数据分析系统&#xff1a;大众点评店铺数据分析系统。 推荐系统的目的是信息过载所…

rockchip 3588 HDMI avmute

概述 HDMI (High-Definition Multimedia Interface) 是一种数字接口标准&#xff0c;用于传输高清视频和多通道音频信号。AVMUTE 是 HDMI 规范中的一个术语&#xff0c;表示"Audio-Video Mute"&#xff08;音视频静音&#xff09;。AVMUTE 通常与 HDMI 设备的音频和…

提高Java程序性能!了解可达性分析算法、强软弱虚引用和三色标记GC的过程,避免不可达对象阻碍程序性能!

文章目录 &#x1f34a; 可达性分析算法&#x1f34a; 强软弱虚引用&#x1f389; 强引用&#x1f389; 软引用&#x1f389; 弱引用&#x1f389; 虚引用 &#x1f34a; 不可达对象GC的过程&#x1f389; GC中不可达对象的回收过程&#x1f4dd; 1. 标记阶段&#x1f4dd; 2. …

远程IO模块物联网应用提高工业自动化生产效率

远程IO模块是一款常用于工业自动化领域的通讯设备&#xff0c;它可以实现远程监测&#xff0c;帮助企业更加有效地掌控生产状态&#xff0c;提高生产效率。远程IO模块的作用是将分散的输入输出信号集中管理&#xff0c;实现实时数据采集、传输与控制。 远程IO模块通过安装在设…

Windows / Ubuntu 连wifi,网线连接旭日X3派以共享网络

首先&#xff0c;PC电脑连好wifi Windows 找到【控制面板->网络和Internet->网络和共享中心->查看网络状态和任务->更改适配器设置】 找到WLAN&#xff0c;右键【属性->共享】勾上允许&#xff0c;然后【确定】。 Ubuntu 打开设置&#xff0c;找到有线设置…

2024SCI经验心得分享---如何在零基础、导师基本放养的情况下---发表自己的第一篇SCI(三区)经验分享篇

本期的经验分享&#xff0c;采访到了我的一位非常非常非常优秀的师妹&#xff0c;师妹于今年6月份投稿&#xff0c;10月份录用&#xff0c;历时四个月录用了自己的第一篇SCI&#xff08;三区&#xff09;的文章图像处理类的&#xff0c;同时师妹也取得了很多其他优秀的荣誉。 众…

Python数据结构(栈)

Python数据结构&#xff08;栈&#xff09; 栈(stack)&#xff0c;有些地方称为堆栈&#xff0c;是一种容器&#xff0c;可存入数据元素、访问元素、删除元素&#xff0c;它的特点在于只能允许在容器的一端(称为栈顶端指标&#xff0c;英语: top)进行加入数据(英语: push)和输…

手撕Vue-实现计算属性

前言 经过上一篇的学习, 完成了将数据代理到了 Nue 的实例上方&#xff0c;这个我们已经撕完了。接下来要实现的是计算属性&#xff0c;计算属性的实现原理是通过 Object.defineProperty() 来实现的&#xff0c;我们先来看看计算属性的使用。 看之前先来改造一下我们的代码基础…

DevExpress WinForms地图组件 - 轻松集成地图功能到应用程序

DevExpress WinForms地图控件允许您在WinForms应用程序中合并地图服务&#xff0c;您可以选择现有的地图资源&#xff0c;如如Bing或OpenStreetMap&#xff0c;或者在公司网络中创建自己的地图数据服务器。DevExpress WinForms地图控件完全支持矢量和笛卡尔坐标地图。 DevExpr…

Plex踩坑——移动缓存目录

plex在生成缩略图、刮削视频的时候会生成大量的缓存文件&#xff0c;占用磁盘空间。 plex默认缓存存储位置为C:\Users\xxx\AppData\Local\Plex Media Server&#xff0c;并且这个路径在plex设置中无法更改。 可以通过修改注册表的方式修改该路径。 首先推出plex账号&#xff…

学习视觉CV Transformer (1)--Transformer介绍

先放Transformer的经典文章 Attention Is All You Need 论文代码&#xff1a;https://paperswithcode.com/paper/attention-is-all-you-need Transformer结构是google在17年的Attention Is All You Need论文中提出&#xff0c;首先主要是在自然语言处理NLP方面应用&#xff0c…

万物“邮”爱,百余志愿者参与邮票艺术共创助力生物多样性

邮票作为生动形象的文化载体&#xff0c;传承着中华文化的历史和文明。自邮票问世以来&#xff0c;就以其精美的设计和图案&#xff0c;成为人们珍藏文化遗产和学习历史文化的窗口。野生动物保护一直是人们所关注的热门话题&#xff0c;相关部门也为宣传、拯救、保护珍贵濒危野…

[量化投资-学习笔记001]Python+TDengine从零开始搭建量化分析平台-数据存储

目录 0. 简介1. 获取交易数据2. 数据库搭建2.1. 数据库安装2.2. 创建数据库2.3. 创建超级表2.4. 创建子表 3.数据导入4. Grafana 安装4.1. 安装Grafana4.2. 安装TDengine插件 附件数据导入脚本历史交易数据-1分钟K线 0. 简介 Python&#xff1a;最常用的量化分析语言&#xff0…

【超参数研究02】使用随机搜索优化超参数

一、说明 在神经网络训练中&#xff0c;超参数也是需要优化的&#xff0c;然而在超参数较多&#xff08;大于3个&#xff09;后&#xff0c;如果用穷举的&#xff0c;或是通过经验约摸实现就显得费时费力&#xff0c;无论如何&#xff0c;这是需要研究、规范、整合的要点&#…

【自用】知识点梳理 自动控制第Z章 离散s

目录标题 离散XXXQ1 离散化的表达式和传递函数怎么匹配上&#xff1f; 离散系统的分析与校正Q ZOH有什么作用K ZOH的Z变换✨K Z变换表格模拟化矫正ZOH的等效Q 为什么离散化之后幅值会变化&#xff1f;Q 模拟化校正中ZOH环节为什么需要等效成惯性环节&#xff1f; 离散化的方法Q…

Android dumpsys介绍

文章目录 一、需求二、环境三、相关概念3.1 dumpsys3.2 Binder3.3 管道 四、dumpsys指令的使用4.1 dumpsys使用4.2 dumpsys指令语法 五、详细设计5.1 dumpsys流程图5.2 dumpsys查看电池信息5.2.1 dumpsys battery指令5.2.2 service->dump打印函数 5.3 dumpsys源码分析5.3.1 …

[support2022@cock.li].faust、[tsai.shen@mailfence.com].faust勒索病毒数据怎么处理|数据解密恢复

引言&#xff1a; 威胁网络安全的恶意软件不断涌现&#xff0c;而[support2022cock.li].faust勒索病毒则是其中的一员。这个网络黑暗角落的新星&#xff0c;以其数据绑架的方式&#xff0c;一度成为数据安全的威胁焦点。本文将探究[support2022cock.li].faust勒索病毒的运作方…

Cypress的安装与启动

目录 一&#xff1a;Cypress介绍 二&#xff1a;安装与使用 1、下载node.js 2、安装Cypress 3、启动Cypress 3、解决异常 三&#xff1a;总结 一&#xff1a;Cypress介绍 Cypress 是为现代网络而构建的下一代前端测试工具&#xff0c;用于解决开发者和 QA 工程师在测试现…

【Hydro】水文模型比较框架MARRMoT - 包含47个概念水文模型的Matlab代码

目录 说明源代码运行实例workflow_example_1.mworkflow_example_2.mworkflow_example_3.mworkflow_example_4.m 测试1、 结构体兼容性问题2、append的兼容性问题3、修改后的MARRMoT_model.m 说明 MARRMoT是一个新的水文模型比较框架&#xff0c;允许不同概念水文模型结构之间的…