简单状压dp(以力扣464为例)

目录

1.状态压缩dp是啥?

2.题目分析

3.解题思路

4.算法分析

5.代码分析

6.代码一览

7.结语


1.状态压缩dp是啥?

顾名思义,状态压缩dp就是将原本会超出内存限制的存储改用更加有效的存储方式。简而言之,就是压缩dp的空间。

举个例子:假设这里有3盏灯,每盏灯的状态只有开和关。请问不改变顺序的前提下开关这些灯,有多少种情况。这里假设0是关闭,1是开启,那么等就有以下八种情况:

如果我们用字符串存储,就需要八个三长度的字符串。但是,我们可以把这些状态看作2进制的序列,那么我们使用一个数字7就可以保存这八种状态,比如数字4转化为二进制就是100,数字1就是001,这就是一种典型的状态压缩。

所以学习状压dp需要一定的位运算的基础哈。


2.题目分析

拿到题面我们要先对数据量进行分析,这里最多是有20个数据,那么比赛中所有可能的情况就是2的20次方种,我们这里是可以进行搜索的。


3.解题思路

我们看题面中给的数字个数有20个,我们就可以使用20位2进制存储排列的情况。然后我们简单的模拟一下游戏过程。假设10有个数:

  • 过程1:

        玩家1:2

        玩家2:3

        玩家1:4

        玩家2:5

        玩家1:?

  • 过程2:

        玩家1:4

        玩家2:3

        玩家1:2

        玩家2:5

        玩家1:?

我们分析一下这两个过程,我们玩家1到达“?”处时,剩余的数字和可选的数字都是一样的,所以这两个情况的结局是一样的。这里可以推理出,如果我们不做任何处理,就会产生大量的重复搜索,所以这里可以使用记忆化搜索或者dp等解题。


4.算法分析

因为本文章讲的是状压dp,所以这里我们选择使用dp进行搜索。这里有n个数字,那么会有2的n种情况,我们计算一下2的20次方个int变量没有超出内存,所以我们可以定义一个数组用来存储搜索过的情况,我们进行搜索的时候,再与这里的状态进行交互。


5.代码分析

int state=(1<<(maxChoosableInteger+1))-1;
vector<int> dp(state+1);

这里题面中的maxChoosableInteger是可以选择的数字个数,这里创建的state代表数字选择的状态,dp就是每个状态下的胜负情况,题目中是需要我们判断先手是不是必胜,所以我们只需要找到一条可以必胜的路线就可以了,如果所有路线都不能胜利,那么就是失败。

    bool canIWin(int maxChoosableInteger, int desiredTotal){if(desiredTotal==0)return true;if(maxChoosableInteger*(maxChoosableInteger+1)/2<desiredTotal)return false;int state=(1<<(maxChoosableInteger+1))-1;vector<int> dp(state+1);return f(desiredTotal,state,dp,maxChoosableInteger);}

上面的这个代码中有两个if,这里是进行特殊判断的,因为如果一开始的数字就是0,就直接判断胜利,因为你不论选择什么数字都可以超过0,下面的if是判断这局的所有和是否可以达到目标值,如果所有的值相加都无法达到目标值,那么就没有胜利者,既然没有胜利者,也就没有所谓的必胜策略。

下面的f就是我们的搜索函数

    bool f(int last,int state,vector<int>& dp,int n){if(last<=0)return false;if(dp[state]!=0){return dp[state] == 1;}bool ret=false;for(int i=1;i<=n;i++){if(((1<<i)&state) && !f(last-i,state^(1<<i),dp,n)){ret=true;break;}}dp[state]= ret ? 1 : -1;return ret;}

这里的last是上次选择后距离目标数的距离,state是数字选择的状态,这里的n就是可以选择的数字的最大值。这里我们采用的递归写法,在这个函数中,我们的两个玩家互相改变先手,什么意思呢?就是当我选完了一个数字,轮到另一个玩家选,那么就相当于剔除了一个数字和改变了目标值的新游戏的先手。所以,当这里递归发现last<=0了说明上一个玩家胜利了,这个玩家就失败了。

下面的if就是判断这个情况有没有被搜索过,如果dp[state]!=0说明这个情况已经被搜索过了,我们直接返回就行,这里我定义1就是胜利-1就是失败,所以这里判定如果是1就返回true。

接下来的for循环之前,我们先假设这次比赛是失败的,然后遍历每一种情况,这里首先需要判断,这个数字没有选择过,只需要判断state上的第i位是不是1就可以了,当然我们还需要判断,下一位玩家是不是失败,这里我们last减去我们选择的数字,然后更新state的状态,如果下手是失败的,那么就可以判断我们本次是成功的。所以ret变为true退出循环。

最后更新dp[state]的值,如果ret是true就赋值为1,否则赋值为-1。保存完毕后返回ret的值就完成了搜索。


6.代码一览

class Solution 
{
public:bool f(int last,int state,vector<int>& dp,int n){if(last<=0)return false;if(dp[state]!=0){return dp[state] == 1;}bool ret=false;for(int i=1;i<=n;i++){if(((1<<i)&state) && !f(last-i,state^(1<<i),dp,n)){ret=true;break;}}dp[state]= ret ? 1 : -1;return ret;}bool canIWin(int maxChoosableInteger, int desiredTotal){if(desiredTotal==0)return true;if(maxChoosableInteger*(maxChoosableInteger+1)/2<desiredTotal)return false;int state=(1<<(maxChoosableInteger+1))-1;vector<int> dp(state+1);return f(desiredTotal,state,dp,maxChoosableInteger);}
};

7.结语

简单状态压缩dp就讲到这里了哈,如果本文有什么错误的地方欢迎大家前来指正呀。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式探索:建造者模式

1. 什么是建造者模式 建造者模式 (Builder Pattern)&#xff0c;也被称为生成器模式&#xff0c;是一种创建型设计模式。 定义&#xff1a;将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 建造者模式要解决的问题&#xff1a; 建造者模…

谷粒商城学习-10-docker安装mysql

文章目录 一&#xff0c;拉取MySQL镜像1&#xff0c;搜索MySQL的Docker镜像2&#xff0c;拉取MySQL镜像3&#xff0c;查看已经拉取的镜像 二&#xff0c;创建、启动MySQL容器1&#xff0c;使用docker run创建启动容器2&#xff0c;使用docker ps查看运行状态的容器3&#xff0c…

力扣-dfs

何为深度优先搜索算法&#xff1f; 深度优先搜索算法&#xff0c;即DFS。就是找一个点&#xff0c;往下搜索&#xff0c;搜索到尽头再折回&#xff0c;走下一个路口。 695.岛屿的最大面积 695. 岛屿的最大面积 题目 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相…

Qt:12.输入类控件(QSpinBox-整数值输入的小部件、QDateEdit、QTimeEdit、QDateTimeEdit- 日期和时间输入的控件)

目录 一、QSpinBox-整数值输入的小部件&#xff1a; 1.1QSpinBox介绍&#xff1a; 1.2属性介绍&#xff1a; 1.3通用属性介绍&#xff1a; 1.4信号介绍&#xff1a; 二、QDateEdit、QTimeEdit、QDateTimeEdit- 日期和时间输入的控件&#xff1a; 2.1QDateEdit、QTimeEdit…

测试面试宝典(一)——你觉得测试和开发需要怎么结合才能使软件的质量得到更好的保障?

“在我看来&#xff0c;测试和开发的有效结合对于保障软件质量至关重要。 首先&#xff0c;在需求分析阶段&#xff0c;测试人员就应该参与进来&#xff0c;与开发人员一起理解软件的需求和功能。这样测试人员可以提前制定测试计划和策略&#xff0c;明确测试的重点和范围。 在…

springboot零食盒子-计算机毕业设计源码50658

目 录 1 绪论 1.1 研究背景 1.2研究意义 1.3论文结构与章节安排 2 微信小程序的零食盒子系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.5本章小结 3 微信…

人工智能算法工程师(中级)课程3-sklearn机器学习之数据处理与代码详解

大家好&#xff0c;我是微学AI,今天给大家分享一下人工智能算法工程师(中级)课程3-sklearn机器学习之数据处理与代码详解。 Sklearn&#xff08;Scikit-learn&#xff09;是一个基于Python的开源机器学习库&#xff0c;它提供了简单有效的数据挖掘和数据分析工具。Sklearn包含了…

【初阶数据结构】树与二叉树:从零开始的奇幻之旅

初阶数据结构相关知识点可以通过点击以下链接进行学习一起加油&#xff01;时间与空间复杂度的深度剖析深入解析顺序表:探索底层逻辑深入解析单链表:探索底层逻辑深入解析带头双向循环链表:探索底层逻辑深入解析栈:探索底层逻辑深入解析队列:探索底层逻辑深入解析循环队列:探索…

后VMware时代,一体化技术平台建设思路

在数字化转型的浪潮中&#xff0c;企业对IT基础设施的需求正在发生根本性的变化。VMware时代的结束&#xff0c;为企业带来了重新构建技术平台的机遇与挑战。6月28日&#xff0c;在主题为【聚力生态&#xff0c;VMware全链替代】的线上研讨会上&#xff0c;灵雀云首席解决方案专…

基于Java+Vue的场馆预约系统源码体育馆羽毛球馆篮球馆预约

市场前景 市场需求持续增长&#xff1a;近年来&#xff0c;随着人们生活水平的提高和休闲娱乐需求的多样化&#xff0c;各类场馆&#xff08;如体育馆、图书馆、博物馆、剧院等&#xff09;的访问量不断增加。然而&#xff0c;传统的预约方式往往存在效率低下、信息不透明等问…

专注于国产FPGA芯片研发的异格技术Pre-A+轮融资,博将控股再次投资

近日&#xff0c;苏州异格技术有限公司&#xff08;以下简称“异格技术”&#xff09;宣布成功完成数亿元的Pre-A轮融资&#xff0c;由博将控股在参与Pre-A轮投资后&#xff0c;持续投资。这标志着继2022年获得经纬中国、红点中国、红杉中国等机构数亿元天使轮融资后&#xff0…

[数仓]四、离线数仓(Hive数仓系统-续)

第8章 数仓搭建-DWT层 8.1 访客主题 1)建表语句 DROP TABLE IF EXISTS dwt_visitor_topic; CREATE EXTERNAL TABLE dwt_visitor_topic (`mid_id` STRING COMMENT 设备id,`brand` STRING COMMENT 手机品牌,`model` STRING COMMENT 手机型号,`channel` ARRAY<STRING> C…

九.核心动画 - 显式动画

引言 本篇博客紧接着上一篇的隐式动画开始介绍显式动画。隐式动画是创建动态页面的一种简单的直接的方式&#xff0c;也是UIKit的动画机制基础。但是它并不能涵盖所有的动画类型。 显式动画 接下来我们就来研究另外一种动画显式动画&#xff0c;它能够对一些属性做指定的动画…

揭秘”大模型加速器”如何助力大模型应用

文章目录 一、大模型发展面临的问题二、“大模型加速器”助力突破困难2.1 现场效果展示2.1.1 大模型加速器——文档解析引擎2.2.2 图表数据提取 三、TextIn智能文档处理平台3.1 在线免费体验3.1.1 数学公式提取3.1.2 表格数据提取 四、acge文本向量化模型4.1 介绍4.2 技术创新4…

从0开始的STM32HAL库学习2

外部中断(HAL库GPIO讲解) 今天我们会详细地学习STM32CubeMX配置外部中断&#xff0c;并且讲解HAL库的GPIO的各种函数。 准备工作&#xff1a; 1、STM32开发板&#xff08;我的是STM32F103C8T6&#xff09; 2、STM32CubeMx软件、 IDE&#xff1a; Keil软件 3、STM32F1xx/ST…

前端使用Vue和Element实现可拖动弹框效果,且不影响底层元素操作,Cesium作为底图(可拖拽的视频实时播放弹框,底层元素可以正常操作)

简述&#xff1a;在前端开发中&#xff0c;弹框和实时视频播放是常见的需求。这里来简单记录一下&#xff0c;如何使用Vue.js和Element UI实现一个可拖动的弹框&#xff0c;并在其中播放实时视频。同时&#xff0c;确保在拖拽弹框时&#xff0c;底层元素仍然可以操作。这里来记…

Effective C++笔记之二十一:One Definition Rule(ODR)

ODR细节有点复杂&#xff0c;跨越各种情况。基本内容如下&#xff1a; ●普通&#xff08;非模板&#xff09;的noninline函数和成员函数、noninline全局变量、静态数据成员在整个程序中都应当只定义一次。 ●class类型&#xff08;包括structs和unions&#xff09;、模板&…

钡铼4G无线RTU助力智慧能源发展实现电网远程调控

随着全球对清洁能源和高效能源管理的需求日益增长&#xff0c;智慧能源技术正逐渐成为推动可持续发展的重要驱动力。在这一背景下&#xff0c;钡铼4G无线远程终端单元正在为智慧能源的发展和电网的远程调控提供强有力的支持。 钡铼4G无线RTU&#xff1a;智慧能源的神经网络 钡…

顺序结构 ( 五 ) —— 数据输入输出 【互三互三】

文章目录 &#x1f341;序 &#x1f341;一、字符输入函数getchar &#x1f341;二、字符输出函数putchar &#x1f341;三、通过cout流输出数据 &#x1f341;四、通过cin流读入数据 &#x1f341;五、格式化输入函数scanf &#x1f341;六、格式化输出函数printf &…

【python】QWidget父子关系,控件显示优先级原理剖析与应用实战演练

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…