力扣 | 递归 | 区间上的动态规划 | 486. 预测赢家

news2024/11/15 17:41:13

文章目录

  • 一、递归
  • 二、区间动态规划

LeetCode:486. 预测赢家
在这里插入图片描述

一、递归

注意到本题数据范围为 1 < = n < = 20 1<=n<=20 1<=n<=20,因此可以使用递归枚举选择方式,时间复杂度为 2 20 = 1024 ∗ 1024 = 1048576 = 1.05 × 1 0 6 2^{20} = 1024*1024=1048576=1.05 × 10^6 220=10241024=1048576=1.05×106

对于每一个先手都有两种选择方式,我们对该选择方式进行枚举。

我们定义递归函数 p r e d i c t predict predict表示玩家1在当前选择的情况下是否可以胜利,注意到每个玩家的玩法都会使他的分数最大化,因此对于玩家2的选择,如果存在一个选择使得玩家1输,那么该情况下玩家1都不能胜利(只要玩家2选择让自己赢的情况,那么玩家1就不能赢了)。但是对于玩家1的选择,存在一个选择能赢就算可以赢。
在这里插入图片描述

class Solution {
public:
    bool predictTheWinner(vector<int>& nums) {
        return predict(nums, 0, (int) nums.size() - 1, 0, 0, 0);
    }
private:
    bool predict(vector<int> & nums, int left, int right, int player, int score_1, int score_2){
        if(left > right){
            if(score_1 >= score_2) return true;
            else return false;
        }
        if(player == 0){//玩家一,存在一个赢就算赢了
            if(predict(nums, left + 1, right, player ^ 1, score_1 + nums[left], score_2)) return true;
            if(predict(nums, left, right - 1, player ^ 1, score_1 + nums[right], score_2)) return true;
        }else{//玩家二,存在一个玩家二赢,则玩家一必输。
            if(predict(nums, left + 1, right, player ^ 1, score_1, score_2 + nums[left]) &&
            predict(nums, left, right - 1, player ^ 1, score_1, score_2 + nums[right])) return true;
        }
        return false;
    }
};

二、区间动态规划

注意到这里是从大的数组中选择,让数组依次减小,我们也可以从数组小的开始转移到大数组,因为当小数组确定时,大数组也能确定。

我们可以定义 d p 1 [ i ] [ j ] [ p l a y e r ] dp1[i][j][player] dp1[i][j][player]表示在选择数组 [ i , j ] [i,j] [i,j]时, p l a y e r player player先手时,玩家1的分数;类似的有 d p 2 [ i ] [ j ] [ p l a y e r ] dp2[i][j][player] dp2[i][j][player]

则有状态转移:

//玩家1先手
	dp1[i][j][0] = max(dp1[i + 1][j][1] + nums[i], dp1[i][j - 1][1] + nums[j]);
	if(dp1[i + 1][j][1] + nums[i] >= dp1[i][j - 1][1] + nums[j]){
		dp2[i][j][0] = dp2[i + 1][j][1];
		if(dp1[i + 1][j][1] + nums[i] == dp1[i][j - 1][1] + nums[j])
			dp2[i][j][0] = min(dp2[i + 1][j][1], dp2[i][j - 1][1]);
	}else{
		dp2[i][j][0] = dp2[i][j - 1][1];
	}
//玩家2先手
	dp2[i][j][1] = max(dp2[i + 1][j][0] + nums[i], dp2[i][j - 1][0] + nums[j]);
	if(dp2[i + 1][j][0] + nums[i] >= dp2[i][j - 1][0] + nums[j]){
		dp1[i][j][1] = dp1[i + 1][j][0];
		if(dp2[i + 1][j][0] + nums[i] == dp2[i][j - 1][0] + nums[j])
			dp1[i][j][1] = min(dp1[i + 1][j][0], dp1[i][j - 1][0]);
	}else{
		dp1[i][j][1] = dp1[i][j - 1][0];
	}

时间复杂度: O ( N 2 ) O(N^2) O(N2)
在这里插入图片描述

class Solution {
public:
    bool predictTheWinner(vector<int>& nums) {
        vector<vector<array<int, 2>>> dp1(nums.size(), vector<array<int, 2>>(nums.size(), array<int, 2>{}));
        vector<vector<array<int, 2>>> dp2(nums.size(), vector<array<int, 2>>(nums.size(), array<int, 2>{}));
        for(int i = 0; i < nums.size(); ++ i){
            dp1[i][i][0] = nums[i];
            dp2[i][i][1] = nums[i];
        }

        for(int k = 1; k < nums.size(); ++ k){
            for(int i = 0; k + i < nums.size(); ++ i){
                int j = i + k;
                //玩家1先手
	            dp1[i][j][0] = max(dp1[i + 1][j][1] + nums[i], dp1[i][j - 1][1] + nums[j]);
	            if(dp1[i + 1][j][1] + nums[i] >= dp1[i][j - 1][1] + nums[j]){
		            dp2[i][j][0] = dp2[i + 1][j][1];
		            if(dp1[i + 1][j][1] + nums[i] == dp1[i][j - 1][1] + nums[j])
			            dp2[i][j][0] = min(dp2[i + 1][j][1], dp2[i][j - 1][1]);
	            }else{
		            dp2[i][j][0] = dp2[i][j - 1][1];
	            }
                //玩家2先手
	            dp2[i][j][1] = max(dp2[i + 1][j][0] + nums[i], dp2[i][j - 1][0] + nums[j]);
	            if(dp2[i + 1][j][0] + nums[i] >= dp2[i][j - 1][0] + nums[j]){
		            dp1[i][j][1] = dp1[i + 1][j][0];
		            if(dp2[i + 1][j][0] + nums[i] == dp2[i][j - 1][0] + nums[j])
			            dp1[i][j][1] = min(dp1[i + 1][j][0], dp1[i][j - 1][0]);
	            }else{
		            dp1[i][j][1] = dp1[i][j - 1][0];
	            }
            }
        }

        return dp1[0][(int) nums.size() - 1][0] >= dp2[0][(int) nums.size() - 1][0];
    }
};

简化代码:(这个代码过了)

简化逻辑:玩家1先手,那么玩家1效益最大,玩家2应该效益要最低。
但这个逻辑感觉存在一定问题,因为玩家1先手,玩家1想要自己的效益最大,这个时候玩家2的效益是跟玩家1的选择有关的,因为棋局完全根据玩家1来决定。所以一开始我并没有直接使用min求解后手。

class Solution {
public:
    bool predictTheWinner(vector<int>& nums) {
        vector<vector<array<int, 2>>> dp1(nums.size(), vector<array<int, 2>>(nums.size(), array<int, 2>{}));
        vector<vector<array<int, 2>>> dp2(nums.size(), vector<array<int, 2>>(nums.size(), array<int, 2>{}));
        for(int i = 0; i < nums.size(); ++ i){
            dp1[i][i][0] = nums[i];
            dp2[i][i][1] = nums[i];
        }

        for(int k = 1; k < nums.size(); ++ k){
            for(int i = 0; k + i < nums.size(); ++ i){
                int j = i + k;
                //玩家1先手
	            dp1[i][j][0] = max(dp1[i + 1][j][1] + nums[i], dp1[i][j - 1][1] + nums[j]);
                dp2[i][j][0] = min(dp2[i + 1][j][1], dp2[i][j - 1][1]);
                //玩家2先手
	            dp2[i][j][1] = max(dp2[i + 1][j][0] + nums[i], dp2[i][j - 1][0] + nums[j]);
		        dp1[i][j][1] = min(dp1[i + 1][j][0], dp1[i][j - 1][0]);
            }
        }

        return dp1[0][(int) nums.size() - 1][0] >= dp2[0][(int) nums.size() - 1][0];
    }
};

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

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

相关文章

Linux--目录与文件操作函数

一、目录和&#xff08;硬&#xff09;链接 可在 shell 中利用 ln 命令为一个业已存在的文件创建新的硬链接 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 2. 同一文件的所有名字&#xff08;链接&#xff09;地位平等—没有一个名字&#xff08;比如…

计应8-01-作业1-静态网页

IP C:\Users\WL>ipconfig // win 查看 ip Windows IP 配置以太网适配器 以太网: //连接特定的 DNS 后缀 . . . . . . . :本地链接 IPv6 地址. . . . . . . . : fe80::6c95:9da6:140c:c59e%13IPv4 地址 . . . . . . . . . . . . : 192.168.51.243//子网掩码 . . . .…

mysql阿拉伯数字转换中文数字函数

函数如下 1.中间一部分代码可以提取出来作为公共方法&#xff0c;我这里并没有提取&#xff0c;因为我是在代码中动态添加的 2.样式目前只做了&#xff1a;123转为一百二十三这类的 drop function if EXISTS zz_convert_number_chinese; create FUNCTION zz_convert_number_…

ELK系列之四---如何通过Filebeat和Logstash优化K8S集群的日志收集和展示

前 言 上一篇文章《日志不再乱: 如何使用Logstash进行高效日志收集与存储》介绍了使用ELK收集通用应用的日志&#xff0c;在目前大多应用都已运行在K8S集群上的环境&#xff0c;需要考虑怎么收集K8S上的日志&#xff0c;本篇就介绍一下如何使用现有的ELK平台收集K8S集群上POD的…

新型供应链攻击手法 — “Revival Hijack”

JFrog 的网络安全研究人员发现了一种名为“Revival Hijack”的新型 PyPI 攻击技术&#xff0c;该技术利用包删除策略绕过安全检查。据统计&#xff0c;超过 22,000 个程序包处于风险之中&#xff0c;可能会影响数十万名用户。 JFrog 的网络安全研究人员发现了一种用于攻击 Pyth…

易灵思时钟输出问题记录

在添加 GPIO时&#xff0c;设置Mode为clkout,并在output Clock中输入时钟名。 这里需要 注意的是&#xff0c; 1. 时钟名不能从core直接输出&#xff0c;而只能使用interface中使用的时钟&#xff0c;如PLL输出的时钟或者GCLK输入的时钟。 2. 易灵思输出时钟不能做其他用途&a…

2024中国产业园区运营商50强榜单揭晓:行业洗牌加速,数智化是关键!

近日&#xff0c;备受瞩目的“2024年度中国产业园区运营商50强”榜单正式揭晓&#xff0c;不仅照亮了行业内的领军之星&#xff0c;更为我们揭示了产业园区运营管理平台在推动经济转型升级中的关键力量与未来趋势的璀璨图景。 从以上产业园区运营商 50 强的角度来看&#xff0…

30岁程序员的焦虑:转行还是继续死磕?现在什么方向更有前景?

最适合转入AI大模型的莫过于程序员和在读大学生了吧。 对于程序员来说&#xff0c;码农之路并不是一帆风顺。对于每一个入行IT业的社会青年来说&#xff0c;谁不是抱着想要成为最高峰的技术大咖或者跃进管理岗的小目标&#xff1f; 然而往往更多的人并非互联网吹捧的如此耀眼…

云原生技术:‌引领数字化转型的新浪潮

云原生技术&#xff1a;‌引领数字化转型的新浪潮 在数字化转型的时代背景下&#xff0c;‌企业面临着前所未有的挑战与机遇。‌随着云计算技术的飞速发展&#xff0c;‌云原生技术作为一种新型的应用程序开发和部署方式&#xff0c;‌正逐步成为构建高可用、‌可扩展应用程序…

MySQL复习1

基本概念 OLTP OLTP&#xff08;On-Line transaction processing&#xff09;翻译为联机事物处理&#xff1b;主要对数据库增删改查。 OLTP 主要用来记录某类业务事件的发生&#xff1b;数据会以增删改查的方式在数据库中更新处理操作&#xff0c;要求实施性强&#xff0c;稳…

OS_程序的装入与链接

2024.09.05&#xff1a;操作系统程序的装入与链接学习笔记 第12节 程序的装入与链接 2.1 程序的装入2.1.1 绝对装入方式2.1.2 可重定位装入方式&#xff08;静态重定位&#xff09;2.1.3 动态运行时装入方式&#xff08;动态重定位&#xff09; 2.2 程序的链接2.2.1 静态链接方…

LIN总线CAPL函数—— 检查LIN报头的时间(ChkStart_LINHeaderToleranceViolation

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

高级算法设计与分析 学习笔记3 哈希表

首先我们要讨论一个把n个数据放到列表S里面的问题&#xff1a; 但很显然&#xff0c;这些数据的范围有多大这个T就得有多大&#xff0c;而实际上要放的数字可能就几个&#xff08;比如就放一个1和一个10000000&#xff0c;那我还是要准备一个巨大的T&#xff09;&#xff0c;不…

【STM32】cubemx配置GPIO

直接使用STM32CubeMX点灯 使用之前的工程 配置GPIO 对四个灯设置GPIO输出 close后直接打开keil 演示

基于LangChain+LLM的相关技术研究及初步实践

0 1 概述 大模型概述 大模型是指具有大规模参数和复杂计算结构的机器学习模型。这些模型通常由深度神经网络构建而成&#xff0c;拥有数十亿甚至数千亿个参数。大模型的设计目的是为了提高模型的表达能力和预测性能&#xff0c;能够处理更加复杂的任务和数据。大模型在各种领…

提高 Facebook 参与度的 8个技巧

在社交媒体中&#xff0c;Facebook仍然是企业与受众建立联系的重要渠道。无论你是刚刚建立 Facebook 业务主页&#xff0c;还是经验丰富的营销人员&#xff0c;都必须了解人们如何跟你的主页互动。 一、什么是 Facebook 参与度&#xff1f; Facebook的参与度是指用户对你的 F…

潜望长焦+快充:vivo X200系列,小尺寸手机的大突破

在智能手机市场日益激烈的竞争中&#xff0c;厂商们不断推陈出新&#xff0c;以满足消费者多样化的需求。vivo作为中国知名的智能手机品牌&#xff0c;一直以其创新的设计和强大的功能赢得市场的认可。 近日&#xff0c;vivo X200系列的即将发布引起了广泛关注&#xff0c;特别…

开学季装机必备软件 向日葵远程控制,手机也能变电脑

暑假转眼结束&#xff0c;又来到了9月开学季。 这个时间点&#xff0c;不少同学会选择为自己购置一台电脑&#xff0c;放置在宿舍使用。 一台全新的PC电脑该安装哪些软件呢&#xff1f;基本的办公全家桶不用多说&#xff0c;steam、epic等游戏娱乐平台更是无需多言。除此之外…

Spring Cloud Gateway学习记录

Spring中文网 https://springdoc.cn/spring-cloud-gateway/ Spring官网 https://spring.io/projects/spring-cloud-gateway 网关简介 大家都都知道在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f; 如果…

如何恢复格式化的 Android 智能手机

如何恢复Android手机上格式化的数据 格式化智能手机的存储卡后&#xff0c;您想恢复图片、视频、音乐吗&#xff1f;您想从 Android 手机中恢复已删除的文本吗&#xff1f;格式化存储卡后&#xff0c;如何恢复存储卡上的图片&#xff1f; 使用奇客数据恢复&#xff0c;这款特…