简单状压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.mzph.cn/pingmian/44670.shtml

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

相关文章

VB 函数

VB 函数 Visual Basic(VB)是一种由微软开发的高级编程语言,广泛用于开发Windows桌面应用程序。在VB中,函数是一段执行特定任务的代码,它可以返回一个值。本文将详细介绍VB中的函数,包括基本概念、类型、语法和示例。 基本概念 函数是一段可重用的代码,用于执行特定的…

jdk中自带的并发类

1、seamplore 信号量 countDownLaunch&#xff1a;等待所有线程都完成&#xff0c;主线程在执行 CyclicBarrirer 内存屏障 exchanger 线程之间交换数据 phaser 阶段协同器 阻塞队列

AWS-WAF-Log S3存放,通过Athena查看

1.创建好waf-cdn 并且设置好规则和log存储方式为s3 2. Amazon Athena 服务 使用 &#xff08;注意s3桶位置相同得区域&#xff09; https://docs.aws.amazon.com/zh_cn/athena/latest/ug/waf-logs.html#waf-example-count-matched-ip-addresses 官方文档参考,建一个分区查询表…

C. Earning on Bets

题目 个人补充&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 #define ll long longconst int maxn 1e6 5, in…

C语言 | Leetcode C语言题解之第228题汇总区间

题目&#xff1a; 题解&#xff1a; char** summaryRanges(int* nums, int numsSize, int* returnSize) {char** ret malloc(sizeof(char*) * numsSize);*returnSize 0;int i 0;while (i < numsSize) {int low i;i;while (i < numsSize && nums[i] nums[i …

算法通关:004_1选择排序

代码一定要自己手敲理解 public class _004 {//选择排序&#xff0c;冒泡排序&#xff0c;插入排序//交换public static void swap(int[] arr,int i ,int j){int temp arr[i];arr[i] arr[j];arr[j] temp;}//选择排序public static void selectSort(int[] arr){if(arr null…

YOLOv10改进 | Conv篇 | 利用FasterBlock二次创新C2f提出一种全新的结构(全网独家首发,参数量下降70W)

一、本文介绍 本文给大家带来的改进机制是利用FasterNet的FasterBlock改进特征提取网络&#xff0c;将其用来改进ResNet网络&#xff0c;其旨在提高计算速度而不牺牲准确性&#xff0c;特别是在视觉任务中。它通过一种称为部分卷积&#xff08;PConv&#xff09;的新技术来减少…

NLP入门——词袋语言模型的搭建、训练与预测

卷积语言模型实际上是取了句子最后ctx_len个词作为上下文输入模型来预测之后的分词。但更好的选择是我们做一个词袋&#xff0c;将所有分词装在词袋中作为上下文&#xff0c;这样预测的分词不只根据最后ctx_len个分词&#xff0c;而是整个词袋中的所有分词。 例如我们的序列是&…

javaweb图书商城系统带万字文档网上书城java项目java课程设计java毕业设计

文章目录 图书商城系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带万字文档&#xff08;9.9&#xffe5;带走&#xff09; 图书商城系统 一、项目演示 网上书城 二、项目介绍 语言&#xff1a;java 数据库&#xff1a;…

ABAP中结合销售订单创建交货单的BAPI函数的使用方法

在ABAP中&#xff0c;结合销售订单创建交货单的BAPI是BAPI_OUTB_DELIVERY_CREATE_SLS。这个BAPI允许你基于一个或多个销售订单行项目来创建交货单。 如何使用BAPI_OUTB_DELIVERY_CREATE_SLS 准备数据&#xff1a; 确定销售订单号码和行项目号码。准备交货单的头数据&#xff0…

typora 两边太宽,设置宽度

步骤&#xff1a; 查看目前使用主题类型 文件 —> 偏好设置 —> 外观 —> 打开主题文件夹 修改对应的主题&#xff1a;max-width

MySQL 数据库支持存储emoji表情

当你通过node.js&#xff0c;往mysql存储emoji表情的时候&#xff0c;可能会遇到报错&#xff1a; code: ‘ER_TRUNCATED_WRONG_VALUE_FOR_FIELD’, errno: 1366, sqlMessage: “Incorrect string value: ‘\xF0\x9F\x8D\x94’ for column ‘nick_name’ at row 1”, sqlState…

AI推介-大语言模型LLMs之RAG(检索增强生成)论文速览(arXiv方向):2024.06.01-2024.06.20

文章目录&#xff5e; 1.StackRAG Agent: Improving Developer Answers with Retrieval-Augmented Generation2.FoRAG: Factuality-optimized Retrieval Augmented Generation for Web-enhanced Long-form Question Answering3.Model Internals-based Answer Attribution for T…

MySQL数据库主从复制+mycat读写分离+MHA实操

目录 一、主从复制 1.1 主从复制简介 1.2 MySQL支持的复制类型 1.3 主从复制的工作过程 1.4 主从复制的同步模式 1.4.1 异步复制&#xff08;Asynchronous replication&#xff09; 1.4.2 全同步复制&#xff08;Fully synchronous replication&#xff09; 1.4.3 半同…

力扣2356.二维差分模板——子矩阵元素加1

力扣2356.二维差分模板——子矩阵元素加1 模板题 最后将n2*n2的矩阵删去周围一圈变成n*n矩阵的操作 class Solution {public:vector<vector<int>> rangeAddQueries(int n, vector<vector<int>>& queries) {vector<vector<int>> res…

MyBatis(36)MyBatis 中如何有效地管理 SQL 语句

在MyBatis中有效地管理SQL语句是非常重要的&#xff0c;尤其是当面对较大或复杂的项目时。有效地管理SQL语句可以提高代码的可维护性、可读性和可重用性。以下是一些在MyBatis中有效管理SQL语句的策略&#xff1a; 1. 使用Mapper XML文件 MyBatis通过Mapper XML文件允许你将S…

前端 JS 经典:字符串比较

题目&#xff1a;比较两个字符串大小&#xff0c;两个字符串都是用-连接的数字&#xff0c;比如 1-2-33-55。比较方式是从左到右&#xff0c;依次比较每个数字的大小&#xff0c;遇到相等的数字继续往后比较&#xff0c;遇到不同的数字直接得到结果。 思路&#xff1a;定义一个…

【ubuntu22.04 安装软件报错】

ubuntu22.04 安装软件报错 报错信息&#xff1a; E: 文件 list 第 1 行的记录格式有误 /etc/apt/sources.list.d/archive_uri-http_security_ubuntu_com_ubuntu-jammy.list (Component)E: 无法读取源列表。分析 以前ubuntu安装软件使用的软件源是记录在 /etc/apt/sources.li…

【JavaWeb程序设计】Servlet(二)

目录 一、改进上一篇博客Servlet&#xff08;一&#xff09;的第一题 1. 运行截图 2. 建表 3. 实体类 4. JSP页面 4.1 login.jsp 4.2 loginSuccess.jsp 4.3 loginFail.jsp 5. mybatis-config.xml 6. 工具类&#xff1a;创建SqlSessionFactory实例&#xff0c;进行 My…

UI设计工具选择指南:Sketch、XD、Figma、即时设计

在数字产品设计产业链中&#xff0c;UI设计师往往起着连接前后的作用。产品经理从一个“需求”开始&#xff0c;制定一个抽象的产品概念原型。UI设计师通过视觉呈现将抽象概念具体化&#xff0c;完成线框图交互逻辑视觉用户体验&#xff0c;最终输出高保真原型&#xff0c;并将…