Leetcode.486 预测赢家

2023-09-17 20:05:06

题目链接

Leetcode.486 预测赢家 mid

题目描述

给你一个整数数组 nums 。玩家 1 1 1 和玩家 2 2 2 基于这个数组设计了一个游戏。

玩家 1 1 1 和玩家 2 2 2 轮流进行自己的回合,玩家 1 1 1 先手。开始时,两个玩家的初始分值都是 0 0 0 。每一回合,玩家从数组的任意一端取一个数字(即, n u m s [ 0 ] nums[0] nums[0] n u m s [ n u m s . l e n g t h − 1 ] nums[nums.length - 1] nums[nums.length1]),取到的数字将会从数组中移除(数组长度减 1 1 1 )。玩家选中的数字将会加到他的得分上。当数组中没有剩余数字可取时,游戏结束。

如果玩家 1 1 1 能成为赢家,返回 true 。如果两个玩家得分相等,同样认为玩家 1 1 1 是游戏的赢家,也返回 true 。你可以假设每个玩家的玩法都会使他的分数最大化。

示例 1:

输入:nums = [1,5,2]
输出:false
解释:一开始,玩家 1 可以从 1 和 2 中进行选择。
如果他选择 2(或者 1 ),那么玩家 2 可以从 1(或者 2 )和 5 中进行选择。如果玩家 2 选择了 5 ,那么玩家 1 则只剩下 1(或者 2 )可选。
所以,玩家 1 的最终分数为 1 + 2 = 3,而玩家 2 为 5 。
因此,玩家 1 永远不会成为赢家,返回 false 。

示例 2:

输入:nums = [1,5,233,7]
输出:true
解释:玩家 1 一开始选择 1 。然后玩家 2 必须从 5 和 7 中进行选择。无论玩家 2 选择了哪个,玩家 1 都可以选择 233 。
最终,玩家 1(234 分)比玩家 2(12 分)获得更多的分数,所以返回 true,表示玩家 1 可以成为赢家。

提示:
  • 1 ≤ n u m s . l e n g t h ≤ 20 1 \leq nums.length \leq 20 1nums.length20
  • 0 ≤ n u m s [ i ] ≤ 1 0 7 0 \leq nums[i] \leq 10^7 0nums[i]107

解法:记忆化搜索

我们定义 d f s ( i , j ) dfs(i,j) dfs(i,j)当前先手 处于 ( i , j ) (i,j) (i,j) 的局面,所能获得的最大的分。

  • 当前先手 选择 n u m s [ i ] nums[i] nums[i] 就会使得后手处于 ( i + 1 , j ) (i + 1,j) (i+1,j) 局面,即后手的最大得分为 d f s ( i + 1 , j ) dfs(i + 1,j) dfs(i+1,j)
  • 当前先手 选择 n u m s [ j ] nums[j] nums[j] 就会使得后手处于 ( i , j − 1 ) (i ,j - 1) (i,j1) 局面,即后手的最大得分为 d f s ( i , j − 1 ) dfs(i ,j - 1) dfs(i,j1)

先手要让后手得分尽可能的小,所以先手直接让后手选择较小的那个得分,即 m i n { d f s ( i + 1 , j ) , d f s ( i , j − 1 ) } min\{ dfs(i + 1,j),dfs(i ,j - 1)\} min{dfs(i+1,j),dfs(i,j1)}

因为无论怎么选择,先手后手得分总和是相同的。所以,后手的得分已经确定,那么此时先手的得分为 s u m ( i , j ) − m i n { d f s ( i + 1 , j ) , d f s ( i , j − 1 ) } sum(i,j) - min\{ dfs(i + 1,j),dfs(i ,j - 1)\} sum(i,j)min{dfs(i+1,j),dfs(i,j1)}

i = j i = j i=j 时,此时先手只能选择 n u m s [ i − 1 ] nums[i-1] nums[i1](下标从 1 1 1 开始)。

最后我们只需要判断 d f s ( 1 , n ) dfs(1,n) dfs(1,n) 是否大于总分 s u m ( 1 , n ) sum(1,n) sum(1,n) 的一半,即 d f s ( 1 , n ) × 2 ≥ s u m ( 1 , n ) dfs(1,n) \times 2 \geq sum(1,n) dfs(1,n)×2sum(1,n)

时间复杂度: O ( n 2 ) O(n^2) O(n2)

C++代码:

class Solution {
public:
    bool predictTheWinner(vector<int>& nums) {
        int n = nums.size();
        vector<int> s(n + 1);
        for(int i = 1;i <= n;i++) s[i] = s[i - 1] + nums[i - 1];

        auto get = [&](int l,int r)->int{
            return s[r] - s[l - 1];
        };

        int f[n + 1][n + 1];
        memset(f,-1,sizeof f);

        function<int(int,int)> dfs = [&](int i,int j)->int{
            if(f[i][j] != -1) return f[i][j];
            if(i == j){
                f[i][j] = nums[i - 1];
                return f[i][j];
            }

            f[i][j] = get(i,j) - min(dfs(i + 1,j),dfs(i,j - 1));

            return f[i][j];
        };

        return dfs(1,n) * 2 >= get(1,n);
    }
};
更多推荐

华为云云耀云服务器L实例评测|使用docker部署禅道系统

大家好,我是早九晚十二,目前是做运维相关的工作。写博客是为了积累,希望大家一起进步!我的主页:早九晚十二文章目录前言准备工作华为云账号注册充值、购买服务器服务器操作密码修改登录远程工具禅道部署简介部署安装docker设置开机自启禅道镜像包获取查找并拉取镜像创建docker容器并启动开启防火墙入站策略浏览器访问IP:PO

【2023】Jenkins入门与安装

目录1.什么是Jenkins2.Jenkins安装部署3.配置Jenkins4.优化Jenkins5.插件管理5.1.联网安装5.2.hpi文件安装5.3.离线安装6.创建项目操作系统:centos7.9JAVA版本:java-11-openjdkJenkins版本:jenkins-2.401.11.什么是Jenkin

【C++】day6学习成果:继承、多态、栈和循环队列

1.将之前定义的栈类和队列类都实现成模板类栈:#include<iostream>#defineMAX8usingnamespacestd;template<typenameT>classStack{private:T*data;//栈的数组,指向堆区空间,用于存储栈的容器inttop;//记录栈顶的变量public:

潮力全开!泡泡玛特泰国首店盛大开业 限定单品点燃玩家热情

9月20日,泡泡玛特泰国首店盛大开业,吸引超千名粉丝现场排队,并在当地社交媒体引发热议。多家泰国主流媒体对此给予了关注和报道。该店坐落的尚泰世界购物中心(CentralWorld)位于泰国曼谷CBD商圈,是目前东南亚地区第二大购物中心,也是曼谷最大的百货购物中心。此前,泡泡玛特就宣布与全球最大的酒店、餐馆以及零售业集团

基于Java的设计模式-策略模式

策略模式就是定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。基本概念策略模式主要是解决多种算法相似的情况下,使用if...else所带来的复杂和难以维护。当存在系统中有多个类,但是区分它们的是只是它们的直接行为,那我们可以把这些封装成一个一个类,然后进行任意替换。策略模式存在三种角色:Strategy策略

PyCharm:No Python interpreter configured for the project

一、问题概述Your的Pycharm软件创建完项目后,结果无法运行,观察后,在Pycharm代码编辑区上面出现了这样的一个黄色条提示:NoPythoninterpreterconfiguredfortheproject【问题】在您的Python项目中无Python解释器,Pycharm只是一个python代码编辑器,而

LuatOS-SOC接口文档(air780E)--camera - codec - 多媒体-编解码

常量常量类型解释codec.MP3numberMP3格式codec.WAVnumberWAV格式codec.AMRnumberAMR-NB格式,一般意义上的AMRcodec.AMR_WBnumberAMR-WB格式codec.create(type,isDecoder)创建编解码用的codec参数传入值类型解释int多

ElasticSearch查询工具类分享

文章目录1.sql转ES工具2.KibanaVSPostman/ApiPost3.esjson转java4.ElasticSearch查询工具类esHelper5.在IDE控制台看到效果如图前言最近需要对ES数据进行分析和查询,之前因为在入门ES时没有好好做笔记和整理。1.sql转ES工具https://printlo

【MySQL从删库到跑路 | 基础第二篇】——谈谈SQL中的DML语句

个人主页:兜里有颗棉花糖欢迎点赞👍收藏✨留言✉加关注💓本文由兜里有颗棉花糖原创收录于专栏【MySQL学习专栏】🎈本专栏旨在分享学习MySQL的一点学习心得,欢迎大家在评论区讨论💌前言前面我们已经讲解了SQL语句中的DDL语句。今天我们继续来学习SQL的DML语句。DML是数据操作语言,用于对库中表的数据操作进行

网络协议 — syslog 协议与 rsyslog 日志服务

目录文章目录目录syslog协议FacilitySeverityActionrsyslog软件架构rsyslogd服务rsyslog.confMODULESGLOBALDIRECTIVESRULS属性替代模板渲染过滤规则Filter模块队列远端日志文件服务器部署示例客户端服务器验证将日志存储至MySQL部署示例服务器验

ASO优化之如何给应用选择竞争对手

在选择竞争对手过程中,最常见的错误之一是没有考虑到自己的应用与同一行业的其他应用相比的范围。例如如果我们刚刚发布了一个应用程序,那么最好的办法就是专注于研究和自己同一级别的应用。1、研究主要关键词。首先选择5到10个可以定义产品类型的主要关键词,找到它们后,需要在GooglePlay、AppStore或其他应用商店内,

热文推荐