877. 石子游戏

news2025/1/11 8:11:29

877. 石子游戏

    • 题目
    • 算法设计:奇偶
    • 算法设计:动态规划

 


题目


 


算法设计:奇偶

最简单的情况,只有2堆石子(石子奇数),先稳赢。

但是四堆情况不同了,如 [3 7 2 3]。

不能直接选最大的,只能选数组开头和末尾。

那我们就按照取法的顺序,把 3 7 2 3 分成 2 组,偶数组 7 3,和奇数组 3 2。

  • 如 3 7 2 3,先手要赢,必须取到 7,怎么可以取到 7 呢?
  • 7 是奇数,就取奇数组,7 是偶数,就取偶数组,因为奇数、偶数必然有一个更大,先手必然赢。
  • 先手取第一个(奇数),后手只能取第二、四个(偶数),继续维持奇偶性质即可
  • 先手取第四个(偶数),后手只能取第一、三个(奇数),继续维持奇偶性质即可

因为石子是奇数,堆数是偶数,取法只能是数组开头和结尾,你的取法要么是奇数组,要么是偶数组。

那么只需要计算出,哪个组大,先手就取哪个组即可。

class Solution {
public:
    bool stoneGame(vector<int>& piles) {
        return true;       // 先手必赢
    }
};

 


算法设计:动态规划

官方的题解的状态是这样定义的: dp(i, j) 为先手可以获得的最大分数,初看这个状态很正确,实际是一个非常明显的错误.

因为当我们考虑 dp(i, j) 由 dp(i + 1, j) 转移过来时,即取了头部下标为i的这个数, 然后我们来看 dp(i + 1, j) 这个状态,按照官方的定义 dp(i + 1, j) 这个状态为 Alice 可以获得的最大分数,这里显然是错误的,因为 dp(i + 1, j) 这个状态不是 Alice。

那么正确的状态定义应该是啥?

  • 答案是从区间 [L, R] 这个状态,先手和后手最大石子差

这个状态是不是看起来很简单,而且可能会有很多人疑问,这个状态的 id 怎么没有记录,是 A,还是 B 到达了这个状态呢?

其实这就是这类问题的关键:因为是两个人在博弈,所以从当前状态转移到下一个状态时,就体现了 id 的变化,比如说当前状态是A,因为是两个人在玩,下一个状态就是B,这里很关键。

为什么状态定义为二维 dp[i][j],因为这题和子序列问题一样,是不连续的序列,通常需要俩个指针来定位,如下表:

ii+1j-1j
53461657

分析,最大石子差 f[i][j] 从哪里来?

  • 从左端拿,先手拿 piles[i],后手从 f[i+1][j] 的俩端中选出最大值,双方石子差为 piles[i] - f[i+1][j],结果为正,说明先手赢

  • 从右端拿,先手拿 piles[j],后手从 f[i][j-1] 的俩端中选出最大值,双方石子差为 piles[j] - f[i][j-1],结果为负,说明后手赢

  • 状态转移方程: f [ i ] [ j ] = m a x ( p i l e s [ i ] − f [ i + 1 ] [ j ] ,    p i l e s [ j ] − f [ i ] [ j − 1 ] ) f[i][j] = max(piles[i]-f[i+1][j], ~~piles[j] - f[i][j-1]) f[i][j]=max(piles[i]f[i+1][j],  piles[j]f[i][j1])

代码实现:

  • 状态转移方向:想计算出 f[i][j] 就需要知道 f[i][j-1]、f[i+1][j]。
  • 最简单情况:那 f[i][j-1]、f[i+1][j] 怎么计算出来?最简单的情况是,下图的初始化。
  • 循环遍历方向:为了保证计算 f[i][j] 时,f[i][j-1]、f[i+1][j] 已经计算出来,循环遍历为:

斜着遍历:

或者,反着遍历:

class Solution {
public:
    bool stoneGame(vector<int>& piles) {
        int n = piles.size();
        vector<vector<int>> f(n, vector<int>(n));
        for (int i = 0; i < n; i++)               // 最简单的情况
            f[i][i] = piles[i];
        for (int i = n - 1; i >= 0; i--)          // 反着遍历
            for (int j = i + 1; j < n; j++) {
                int a = piles[i] - f[i + 1][j];
                int b = piles[j] - f[i][j - 1];
                f[i][j] = max(piles[i] - f[i + 1][j], piles[j] - f[i][j - 1]);
            }
        return f[0][n - 1] > 0;                   // 正数,先手赢
    }
};

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

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

相关文章

2023年五大趋势预测 | 大数据分析、人工智能和云产业展望

随着我们迈入2023年&#xff0c;大数据分析、人工智能和云产业将迎来蓬勃的创新和发展阶段 以下是我们预测的&#xff0c;将对行业格局产生重大影响的五大趋势&#xff1a; 世界在剧变&#xff0c;我们需要尽快寻找行业中的方向&#xff0c;迅速重回轨道 2023年&#xff0c;全…

TryHackMe-NahamStore(常见web漏洞 大杂烩)

NahamStore 漏洞赏金web安全 NahamStore的创建是为了测试您在NahamSec的“漏洞赏金狩猎和Web应用程序黑客入门”Udemy课程中学到的知识。 部署计算机&#xff0c;获得 IP 地址后&#xff0c;进入下一步&#xff01; 写在前面 可能我的顺序&#xff0c;跟别人以及题目都不太一…

spring boot集成activemq(windows)

目录 1.环境配置 2.说明 3.服务启动 4.示例 导入依赖 配置文件 service层 配置类 监听器 5.总结 1.环境配置 下载地址&#xff1a;https://activemq.apache.org/components/classic/download/安装&#xff1a;解压缩即可注意每个版本对应的java版本不一样&#xff0c…

分享96个PHP源码,总有一款适合您

PHP源码 分享96个PHP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 96个PHP源码下载链接&#xff1a;https://pan.baidu.com/s/1B-tNZlbfjT_D3n_Y6ZwfDw?pwduq19 提取码&#xff…

共享自助自习室棋p室茶室办公室电竞篮球馆小程序开发

共享自助自习室棋p室茶室办公室电竞篮球馆小程序开发 多场景应用的共享空间预约系统如:棋牌室;共享办公室&#xff0c;电竞篮球馆&#xff0c;自助民宿等。目前该应用已对接门锁和电控。 前端功能// 多场景应用、预约时间自定义、附近门店一目了然、支持门禁支持电控、首页门…

Windows系统安装轻量级高性能Web服务开发框架OAT++

一、软件简介 oat 是一个轻量级高性能 Web 服务开发框架&#xff0c;采用纯 C 编写而成。官网&#xff1a;https://oatpp.io/ 这个坑爹的网址在国内经常打不开&#xff0c;要多刷新几次。Github: https://github.com/oatpp/oatpp 当前版本&#xff1a; 1.3.0 其主要特性…

用PYTHON自动登录SAP GUI

我们都知道&#xff0c;SAP原生的“脚本录制和回放”功能是在用户进入到某一个SAP”用户指定系统“后才可以启用&#xff1a; 也就是说&#xff0c;从这里开始&#xff0c;您可以通过脚本录制&#xff0c;生成用户名、密码的输入和SAP登录过程的完整代码&#xff1b; 那么我们…

第三层:C++对象模型和this指针

文章目录前情回顾C对象模型和this指针类成员变量和类成员函数的储存this指针this指针概念this指针用途用途1解释用途2解释空指针调用成员函数const修饰的成员变量常函数内可以被修改的值突破&#xff01;步入第四层本章知识点&#xff08;图片形式&#xff09;&#x1f389;wel…

Matlab中算法结合Simulink求解直流微电网中功率

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

初识 jQuery(JavaScript 框架)

初识 jQuery&#xff08;JavaScript 框架&#xff09;参考描述jQuery使用 jQuery 的开发优势&#xff08;部分&#xff09;获取jQuery 语法基础语法入口函数$()jQuery 与 $参数DOM 与 jQuery模板获取DOM 对象jQuery 对象转换DOM 对象转换为 jQuery 对象$()jQuery 对象转换为 DO…

Linux系统管理中Nginx和python的安装以及python虚拟环境软件的安装与使用(四)

1、Nginx的安装和配置&#xff1a; 说明&#xff1a;Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器&#xff1b;同时也是一个IMAP、POP3、SMTP代理服务器&#xff1b;Nginx可以作为一个HTTP服务器进行网站的发布处理&#xff0c;另外Nginx可以作为反向代理进…

C++:list结构算法

List 1.元素在逻辑上具有线性次序&#xff0c;物理地址不做限制。 2.哨兵节点&#xff0c;header和trailer&#xff0c;封装后外部不可见。 3.重载操作符[]&#xff0c;实现下标和位置转换。 4.有序查找无序查找 5.前插入算法&#xff0c;首先创建新节点 然后使new成为this节点…

设计模式之代理模式(静态动态)代理

前言&#xff1a;二十三种设计模式中的一种&#xff0c;属于结构型模式。它的作用就是通过提供一个代理类&#xff0c;让我们在调用目标方法的时候&#xff0c;不再是直接对目标方法进行调用&#xff0c;而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥…

PHP设计模式

目录 一、使用设计模式目的 二、设计模式的七大原则 三、创建型模式&#xff08;构建型模式&#xff09; 1、单例模式 代码实例 2、工厂模式 2.1、工厂模式——简单工厂模式 简单工厂模式的代码实例 2.2、工厂模式——工厂方法模式 工厂方法模式的代码实例 2.3、工厂…

java开发环境配置及问题排查

Java程序必须运行在JVM之上&#xff0c;所以&#xff0c;我们第一件事情就是安装JDK。 JDK(Java Development Kit)&#xff0c;是Java开发工具包&#xff0c;它提供了Java的开发环境(提供了编译器javac等工具&#xff0c;用于将java文件编译为class文件)和运行环境(提 供了JVM…

Java内存模型和线程安全

Java内存模型和线程安全Java内存模型引言volatile关键字synchronized关键字Java线程Java线程安全synchronized锁优化锁优化技巧列举自旋锁锁消除锁粗化具体实现轻量级锁偏向锁Java内存模型 引言 对于多核处理器而言,每个核都会有自己单独的高速缓存,又因为这多个处理器共享同一…

JavaWeb-会话技术

JavaWeb-会话技术 1&#xff0c;会话跟踪技术的概述 对于会话跟踪这四个词&#xff0c;我们需要拆开来进行解释&#xff0c;首先要理解什么是会话&#xff0c;然后再去理解什么是会话跟踪: 会话:用户打开浏览器&#xff0c;访问web服务器的资源&#xff0c;会话建立&#xff…

反射机制.

文章目录概述两个疑问关于java.lang.Class的理解获取Class实例的方式哪些类型可以有Class对象了解类的加载器掌握加载配置文件的另一种方式创建运行时类的对象体会动态性获取运行时类的完整结构调用运行时类的制定结构每日一考动态代理概述 1、反射是动态语言的关键 2、动态语…

使用Docker打包镜像并发布

1、docker介绍 Docker 是一个开源的应用容器引擎&#xff0c;以镜像的形式进行发布。docker的图标是一个大鲸鱼驮着许多集装箱在海上航行。大鲸鱼就是docker&#xff0c;集装箱就是一个个容器。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口&#xff0c;每个容器都…

高级Spring之BeanFactory 与 ApplicationContext 的区别

ApplicationContext接口 SpringBootApplication public class A01 {private static final Logger log LoggerFactory.getLogger(A01.class);public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {//启动SpringBoot程序…