Leetcode: NO.486 预测赢家 深度优先+动态规划

2024-04-17 20:08

本文主要是介绍Leetcode: NO.486 预测赢家 深度优先+动态规划,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目

给定一个表示分数的非负整数数组。 玩家 1 从数组任意一端拿取一个分数,随后玩家 2 继续从剩余数组任意一端拿取分数,然后玩家 1 拿,…… 。每次一个玩家只能拿取一个分数,分数被拿取之后不再可取。直到没有剩余分数可取时游戏结束。最终获得分数总和最多的玩家获胜。

给定一个表示分数的数组,预测玩家1是否会成为赢家。你可以假设每个玩家的玩法都会使他的分数最大化。

示例 1:输入:[1, 5, 2]
输出:False
解释:一开始,玩家1可以从12中进行选择。
如果他选择 2(或者 1 ),那么玩家 2 可以从 1(或者 2 )和 5 中进行选择。如果玩家 2 选择了 5 ,那么玩家 1 则只剩下 1(或者 2 )可选。
所以,玩家 1 的最终分数为 1 + 2 = 3,而玩家 25 。
因此,玩家 1 永远不会成为赢家,返回 False 。
示例 2:输入:[1, 5, 233, 7]
输出:True
解释:玩家 1 一开始选择 1 。然后玩家 2 必须从 57 中进行选择。无论玩家 2 选择了哪个,玩家 1 都可以选择 233 。最终,玩家 1234 分)比玩家 212 分)获得更多的分数,所以返回 True,表示玩家 1 可以成为赢家。
提示:1 <= 给定的数组长度 <= 20.
数组里所有分数都为非负数且不会大于 10000000 。
如果最终两个玩家的分数相等,那么玩家 1 仍为赢家。

链接:https://leetcode-cn.com/problems/predict-the-winner

解题记录

设定step[left][right]为在left~right这段区间中玩家1和玩家2的差值,当前玩家1选着

  • 通过递归,选左边为leftScore = nums[left] - dfs(left+1, right);
  • 选右边rightScore = nums[right] - dfs(left, right-1);
  • 最优为差值最大
/*** @author: ffzs* @Date: 2020/9/1 上午7:10*/
public class Solution {int[][] step;int[] nums;public boolean PredictTheWinner(int[] nums) {int n = nums.length;step = new int[n][n];this.nums = nums;for (int[] ints : step) {Arrays.fill(ints, Integer.MIN_VALUE);}return dfs(0, n-1) >= 0;}private int dfs (int left, int right) {if (left > right) return 0;if (step[left][right] != Integer.MIN_VALUE) return step[left][right];int leftScore = nums[left] - dfs(left+1, right);int rightScore = nums[right] - dfs(left, right-1);int score = Math.max(leftScore, rightScore);step[left][right] = score;return score;}
}

在这里插入图片描述

  • 递归是正着想,机器倒着做
  • 动态规划化是倒着想,机器正着做
/*** @author: ffzs* @Date: 2020/9/1 上午8:37*/public class Solution2 {public boolean PredictTheWinner(int[] nums) {int n = nums.length;int[][] dp = new int[n][n];// 先填上分界线for (int i = 0; i < n; i++) dp[i][i] = nums[i];// 因为要获得 ij ,因此需要优先获取i+1,j-1等,所以从后向前获取for (int i = n-2; i >= 0; i--) {for (int j = i+1; j < n; j++) {dp[i][j] = Math.max((nums[i] - dp[i+1][j]), (nums[j] - dp[i][j-1]));}}return dp[0][n-1] >= 0;}
}

在这里插入图片描述

这篇关于Leetcode: NO.486 预测赢家 深度优先+动态规划的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/912722

相关文章

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S

Python动态处理文件编码的完整指南

《Python动态处理文件编码的完整指南》在Python文件处理的高级应用中,我们经常会遇到需要动态处理文件编码的场景,本文将深入探讨Python中动态处理文件编码的技术,有需要的小伙伴可以了解下... 目录引言一、理解python的文件编码体系1.1 Python的IO层次结构1.2 编码问题的常见场景二

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3