第四十七章 动态规划——状态压缩模型

news2024/11/18 15:45:17

第四十七章 动态规划——状态压缩模型

  • 一、什么是状态压缩
  • 二、例题讲解
    • 1、AcWing 1064. 小国王
      • (1)问题
      • (2)思路
      • (3)代码
    • 2、AcWing 327. 玉米田
      • (1)问题
      • (2)思路
      • (3)代码
    • 3、AcWing 292. 炮兵阵地
      • (1)问题
      • (2)思路
      • (3)代码
    • 4、其余比较难的题目

一、什么是状态压缩

根据我们第四十六章学习的状态机模型会发现某一事件会有多个状态,在某些题目中由于状态不同导致其转移方程也不同。那么这种情况下,我们需要用到状态机DP,即记录当前事件所处的状态,根据不同的状态去写方程。

而前一章节中所涉及的状态都是比较少的,所以我们可以凭借几个数字就能表示。但是当状态非常多并且抽象的时候,我们就需要用到今天所讲解的状态压缩。

比如给我们一行6个方格,现在在方格里填充0和1,我们把这一行看作一个事件,填充后的不同结果看作一个事件状态。那么总的事件状态就应该有26个。那么如果高效地表示这么多个状态呢?

我们现在将6个方格看成6位,0和1都看成二进制中的数字,那么这6位数字就会组成一个二进制数。比如000 010就是2。所以此时我们就实现了一个将抽象状态通过二进制压缩成1个十进制数字的过程,这个过程就叫做状态压缩。

二、例题讲解

以下例题作者在之前的文章中都做过详细地讲解,这里只做一些简单地介绍,详细的解答文章作者将附上链接。

1、AcWing 1064. 小国王

(1)问题

在这里插入图片描述

(2)思路

这道题的一个关键思路就是把每一行当作一个事件,然后由上一行推导出下一行的状态,由于每一行不同的状态就会导致下一行有不同的选择,所以我们需要记录一下行的状态,那么就需要将一行压缩为一个整数。

AcWing 1064. 小国王(状态压缩DP)

(3)代码

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=15,K=110,S=1<<10;
long long f[N][K][S];
int n,m;
vector<int>state;
vector<int>st[S];

bool check(int x)
{
    for(int i=0;i+1<n;i++)
    {
        if((x>>i&1)&&(x>>(i+1)&1))return false;
    }
    return true;
}

int get_nums(int x)
{
    int res=0;
    for(int i=0;i<n;i++)
        res+=x>>i&1;
    return res;
}

int main()
{
    cin>>n>>m;
    for(int i=0;i<1<<n;i++)//记录所有对于本行而言合法的状态
        if(check(i))state.push_back(i);
        
    f[0][0][0]=1;
    
    for(int i=1;i<=n+1;i++)//枚举i
    {
        for(int j=0;j<=m;j++)//枚举j
        {
            for(int ss=0;ss<state.size();ss++)//枚举第i-1行的状态
            {
                for(int s=0;s<state.size();s++)//枚举第i行的状态
                {
                    if(!(state[ss]&state[s])&&(check(state[ss]|state[s])))//判断两行之间是否合法
                    {
                        int count=get_nums(state[s]);//计算第i行的国王数目
                        if(j>=count)
                        {
                            f[i][j][state[s]]+=f[i-1][j-count][state[ss]];
                        }
                    }
                }
            }
        }
    }
    cout<<f[n+1][m][0]<<endl;
    return 0;
}


2、AcWing 327. 玉米田

(1)问题

在这里插入图片描述

(2)思路

这道题和小国王那道题如出一辙,只是这道题对地图本身也做了一定的限制,所以我们就多了一个判断的条件。
AcWing 327. 玉米田(状态压缩DP)

(3)代码

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=15,S=1<<12,mod=1e8;
long long g[N],f[N][S];
vector<int>state;
int n,m;
bool check(int x)
{
    for(int i=0;i+1<m;i++)
    {
        if((x>>i&1)&&(x>>(i+1)&1))return false;
    }
    return true;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<m;j++)
        {
            int x;
            cin>>x;
            g[i]+=(!x)*1<<j;
        }
    }
    for(int i=0;i<1<<m;i++)
    {
        if(check(i))state.push_back(i);
    }
    f[0][0]=1;
    for(int i=1;i<=n+1;i++)
    {
        for(int s=0;s<state.size();s++)
        {
            if(g[i]&state[s])continue;
            for(int ss=0;ss<state.size();ss++)
            {
                if(g[i-1]&state[ss])continue;
                if((state[s]&state[ss])==0)
                    f[i][state[s]]=(f[i][state[s]]+f[i-1][state[ss]])%mod;
            }
        }
    }
    cout<<f[n+1][0]<<endl;
    return 0;
}


3、AcWing 292. 炮兵阵地

(1)问题

在这里插入图片描述

(2)思路

这道题和上面两道问题的区别在于,当前行的状态受前面两行的影响,所以我们需要多加一个维度。

AcWing 292. 炮兵阵地(状态压缩DP)

(3)代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=110,M=10,S=110;
int f[N][S][S];
int g[N];
vector<int>state;
int n,m;
bool check(int state)
{
    for (int i = 0; i < m; i ++ )
        if ((state >> i & 1) && ((state >> i + 1 & 1) || (state >> i + 2 & 1)))
            return false;
    return true;
}


int get_nums(int x)
{
    int res=0;
    for(int i=0;i<m;i++)
        res+=(x>>i&1);
    return res;
}

int main()
{
    cin>>n>>m;
    for(int i=2;i<=n+1;i++)
    {
        for(int j=0;j<m;j++)
        {
            char c;
            cin>>c;
            if(c=='H')g[i]+=1<<j;
        }
    }
    for(int i=0;i<1<<m;i++)
        if(check(i))state.push_back(i);

    for(int i=2;i<=n+3;i++)
    {
        for(int j=0;j<state.size();j++)
        {
            if(state[j]&g[i-2])continue;
            for(int s=0;s<state.size();s++)
            {
                if(state[s]&g[i-1])continue;
                for(int ss=0;ss<state.size();ss++)
                {
                    if(state[ss]&g[i])continue;
                    if( (state[j] & state[s]) || (state[j] & state[ss] ) || (state[s] & state[ss]) )
                        continue;
                    else
                        f[i][ss][s]=max(f[i-1][s][j]+get_nums(state[ss]),f[i][ss][s]);
                }
            }
        }
    }
    cout<<f[n+3][0][0]<<endl;
    return 0;
}

4、其余比较难的题目

状态压缩DP——蒙德里安的梦想
状态压缩DP——最短Hamilton路径
这两道题比较难,如果大家想进一步学的话,可以去读一读。

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

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

相关文章

晴天科技冲刺上市:实控人丁一波系本科肄业,粤民投为其股东

近日&#xff0c;浙江晴天太阳能科技股份有限公司&#xff08;下称“晴天科技”&#xff09;预披露更新招股书&#xff0c;准备在深圳证券交易所主板上市。据贝多财经了解&#xff0c;晴天科技曾于2022年7月1日递交招股书&#xff0c;此次更新了截至2022年6月30日的财务数据等信…

AcWing 1072. 树的最长路径(DFS)

[TOC](AcWing 1072. 树的最长路径&#xff08;树形DP)) 一、题目&#xff1a; 二、思路&#xff1a; 为了方便&#xff0c;我们利用下面这个图做讲解&#xff1a; 这颗树的最长路径必定经过的是图中的点&#xff0c;因此&#xff0c;**我们可以去枚举经过图中每个点的最长路…

微星武士gf66电脑系统中途安装失败怎么办?

微星武士gf66电脑系统中途安装失败怎么办&#xff1f;有用户购买的微星武士gf66电脑想要进行电脑系统的重新安装&#xff0c;但是在新系统的安装过程中出现了错误&#xff0c;导致系统无法启动了。这个情况可以使用U盘来重装一个系统&#xff0c;恢复电脑的正常使用&#xff0c…

将springboot项目部署到linux上运行的步骤

前言&#xff1a; 博主看了许多的博客&#xff0c;总结出了最有用的部分&#xff0c;将springboot项目完整的运行在了linux虚拟机上。而不是仅仅只在网页打印一句话&#xff0c;就当做运行成功。运行成功页面如下&#xff1a; 运行成果展示&#xff1a; 接下来废话不多说&…

Python 读取大文件

读取大文件 python读取文件一般情况是利用open()函数以及read()函数来完成&#xff1a; f open(filename,r) f.read() 这种方法读取小文件&#xff0c;即读取大小远远小于内存的文件显然没有什么问题。但是如果是将一个10G大小的日志文件读取&#xff0c;即文件大小大于内存…

“深度学习”学习日记。与学习有关的技巧--正则化

2023.1.29 在机器学习的过程中&#xff0c;过拟合是一个常见的问题。过拟合指的是只能够拟合训练数据&#xff0c;但不能很好的拟合测试数据&#xff1b;机器学习的目的就是提高泛化能力&#xff0c;即便是没有包括在训练数据里的测试数据&#xff0c;也希望神经网络模型可以正…

javafx中gif 内存优化

1.背景 桌面程序对内存消耗要求很高&#xff0c;基本的要求是整个程序控制在500M以内。 这就要求每个功能点的内存消耗尽可能地少&#xff0c;大于50M的内存消耗就要想办法优化。 2.现状 gif的显示会导致程序的内存激增。以数字大脑用的雷达图动画为例进行说明&#xff0c;下…

TypeScript 学习笔记总结(一)

ts学习笔记总结。 文章目录一、什么是TypeScript&#xff1f;二、TypeScript 环境搭建三、TS 类型声明四、TS 类型详解五、TS 类型总结六、TS 编译选项1. tsconfig.json的 作用2. tsconfig.json的 配置选项013. tsconfig.json的 配置选项02七、Webpack 打包ts代码一、什么是Typ…

Bayanay:一款基于Python开发的无线网络安全研究工具

关于Bayanay Bayanay是一款基于纯Python开发的无线网络安全研究工具&#xff0c;在该工具的帮助下&#xff0c;无论你身处何地&#xff0c;都可以轻松地对周围地区的无线网络安全状况进行研究与分析。 该工具可以通过使用HTML5的地理位置定位功能并结合Scapy获取到的SSID信息…

LeetCode刷题系列 -- 25. K 个一组翻转链表

给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节点内部的值&…

zabbix6,0创建监控项与触发器

zabbix_server IP : 172.31.0.5:10051 zabbix_client IP : 172.31.0.9:10050 zabbix_client已经运行了zabbix-agent,这里我用的是版本2 一、 创建监控项 1、 在客户端创建监控脚本 /etc/zabbix/zabbix_agent2.d #默认配置文件路径 2、 创建配置文件&#xff0c;编写监控脚本…

绿光GOQDs-SA氧化石墨烯量子点CdTe-FA-CS修饰CdTe-PEG-CS的制备

绿光GOQDs-SA氧化石墨烯量子点CdTe-FA-CS修饰CdTe-PEG-CS的制备今天小编分享制备GOQDs改性SA复合杂化膜&#xff0c;一起看看吧&#xff1a;GOQDs改性SA复合杂化膜的制备过程&#xff1a;将一系列不同分子量的CS及接枝壳聚糖用少量乙酸-乙酸钠溶液溶解后,加水稀释到一定浓度,用…

经典文献阅读之--FlowFormer(Transformer结构光流估计)

0. 简介 对于视觉SLAM而言&#xff0c;除了使用特征点法来完成VIO以外&#xff0c;还可以使用光流法来完成VIO的估计。而传统的光流法受环境&#xff0c;光照变化严重&#xff0c;所以有时候会出现光流偏差等问题。所以现在有越来越多的工作朝着深度学习的方向扩展&#xff0c…

卷积神经网络中的Conv层和BN层融合细节

BN层 批归一化层&#xff08;Batch Normallization&#xff09;是一种在卷积神经网络模型中大量使用&#xff0c;为了加速模型收敛的技术。为什么CNN 中引入 BN 层可以加速网络的收敛呢&#xff1f;因为将输入的样本数据或特征图&#xff0c;归一化后&#xff0c;改善了输入数…

智云通CRM:如何在初次见面识别客户机会?

有一次&#xff0c;我给一家公司做CRM系统培训之后&#xff0c;他们公司的老总请我吃饭。那是我们第一次见面&#xff0c;在饭桌上&#xff0c;我和他聊天&#xff0c;说&#xff1a;“洛老师&#xff0c;你们的CRM系统功能真的很不错&#xff0c;帮我我解决了很多销售管理上的…

设计模式面试题 一

第一题&#xff1a;阐述设计模式的责任链&#xff1f; 责任链模式定义&#xff1a; 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送 者和接收者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一 个对象处理它为止。 …

Ruoyi-Cloud框架学习-【03 后端启动 + 前端启动】

打开运行基础模块&#xff08;启动没有先后顺序&#xff09; 记得在后台先启动Redis,不然会报错 RuoYiGatewayApplication &#xff08;网关模块 必须&#xff09; &#xff1a; 即前端所有访问需要通过网关而不是直接访问具体接口、网关会对后台的微服务进行转发 RuoYiAuth…

虹科回顾 | 虹科云科技2022年深度好文

2022年&#xff0c;我们一起学习了很多技术文章、优秀案例 我们的关键词是 数据库、BI、文件存储、高性能计算、数据管理、IT 下面一起来回顾虹科云科技过去一年的深度好文吧! 2022虹科云科技深度好文回顾 点击文字均可跳转到相关文章 数据库系列 ● 虹科产品 | 一文详解…

springboot1

让我们快速构建项目并且运行&#xff0c;他就是搭建程序的脚手架 尽可能减少一切xml的相关配置 快速创建一个spring boot的启动项目 在pom.xml中导入父类的启动器 引入父类的依赖 下面我们写一个web的启动器 这个启动器导入了之后 整个web项目需要的依赖也就导入了 并且把版…

【MIUI刷机】旧机降级记录

欢迎来到 Claffic 的博客 &#x1f49e;&#x1f49e;&#x1f49e; 前言&#xff1a; 小米MAX2是我的第一部小米手机&#xff0c;这款发布于2017年5月25日的小米手机已伴随我5年了&#xff0c;现在再次拿起这部手机&#xff0c;依然能勾起我对当时手机圈的记忆。 当时的我对手…