寒假思维训练day21

今天更新一道不错的状态压缩DP题,顺带总结一下状态压缩DP。


                                        摘要:

                                               Part1   浅谈状态压缩DP的理解

                                               Part2   浅谈对状态机DP的理解

                                               Part3   关于状态压缩DP的1道例题


Part1  状态压缩DP

1、状态压缩DP:

事物的状态可能包含多个特征,但是事物的状态之间却可以互相转移,此时我们引入状态压缩DP,将事物的复杂的状态用一个数字来替代,此时事物的状态可以用数组的某个位置表示,从而可以进行状态的转移。

2、常见的状态表示:

(1) 用10进制数字本身表示状态,比如表示当前状态%某个数字的余数等等,这里举一个例子。
(2) 用10进制内蕴含的二进制位表示状态, 01, 表示了每个位置上的两种状态,它既可以表示是否存在,也可以表示数量的奇偶性。

(3) 用10进制内蕴含的K进制(除了10进制和2进制外的其它进制)表示状态,这种题我没见过,但是基于上面我们很容易可以推广。

3、什么时候我们可以用:

首先是在你的状态表示基础上,整体的转移图是一个拓扑图,也就是可以通过递推得来,并且时间空间可以过得去,此时我们就可以用状态压缩DP。


Part2 状态机DP

我在之前写过一篇关于状态机DP的文章,里面有详细的理论和几道很好的例题:

http://t.csdnimg.cn/POtFs


Part3  例题: 小红的回文数

题目链接:E-小红的回文数_牛客周赛 Round 32 (nowcoder.com)

(1)题意:

小红定义一个整数是“好数”,当且仅当该整数通过重排之后可以形成回文数。(可以包含前导零)现在小红拿到了一个正整数x,小红想截取一段连续区间得到好数,她想知道有多少种不同的方案? 1<= x <= 10^{10^5}


(2)题解: 

暴力显然会超时,必定需要n * n 的复杂度,此时我们不妨考虑一下DP,  我们此时从左到右去考虑这个数,我们考虑每个以第i位数结尾的情况,最后答案就是累加后的值,我们此时考虑一下以第i位数结尾的区间,我们发现对于一个数字而言,每位的数字只能是0-9的数字之一,我们不妨用10个二进制位表示每一种数字的数量%2是多少,这样我们就可以通过统计1的个数判断有几个奇数,如果要构造一个回文串,显然只能由一个或者0个奇数的位。
状态转移方程:F[i][state],表示以第i位数结尾的数字区间,且0-9各个的数字情况是state的方案数,F[i][state1] = F[i - 1][state1 \oplus (1 << a[i])],并且对于每个位单独一位的情况也要考虑,所以状态转移代码是: 

    vector<vector<int>> dp(n + 1, vector<int>((1 << 10) + 2)); 
    dp[0][0] = 1;  
    for(int i = 1; i <= n; i ++ ) {
        for(int j = 0; j < (1 << 10); j ++ ) {
            int k = j ^ (1 << (s[i - 1] - '0'));
            dp[i][k] += dp[i - 1][j]; 
        }
        if(i >= 2) dp[i][1 << (s[i - 1] - '0')] ++; 
    }

你以为事情结束了吗,这是一道比较毒瘤的题,它会卡你的空间,在此基础上我们需要引入滚动数组优化,优化掉一维的空间。
此时的转移代码是:

    dp[0] = 1;  
    long long res = 0; 
    for(int i = 1; i <= n; i ++ ) {
        memset(usdp, 0, sizeof usdp); 
        for(int j = 0; j < 1 << 10; j ++ ) 
            usdp[j ^ (1 << (s[i - 1] - '0'))] += dp[j];
        if(i >= 2) usdp[1 << (s[i  - 1] - '0')] ++; 
        for(int j = 0; j < 1 << 10; j ++ ) {
            cnt = 0; 
            for(int c = 0; c <= 9; c ++ ) 
                if(j >> c & 1) ++ cnt; 
            if(cnt <= 1) res += usdp[j]; 
            dp[j] = usdp[j]; 
        }
    }
    cout << res << endl; 

(3) 代码 (C ++):

滚动数组优化:
 

#include <bits/stdc++.h>
// #define int long long 
#define lowbit(x) (x&-x)
using namespace std; 
const int N = 1e5 + 2; 
const int inf = 0x3f3f3f3f; 
int n, cnt; 
long long dp[2025], usdp[2025];  
// int a[N]; 
void solve() {
    string s; 
    cin >> s; 
    n = s.size();
    cnt = 0; 
//     for(int i = 1; i <= n; i ++ ) a[i] = s[i - 1] - '0';  
    dp[0] = 1;  
    long long res = 0; 
    for(int i = 1; i <= n; i ++ ) {
        memset(usdp, 0, sizeof usdp); 
        for(int j = 0; j < 1 << 10; j ++ ) 
            usdp[j ^ (1 << (s[i - 1] - '0'))] += dp[j];
        if(i >= 2) usdp[1 << (s[i  - 1] - '0')] ++; 
        for(int j = 0; j < 1 << 10; j ++ ) {
            cnt = 0; 
            for(int c = 0; c <= 9; c ++ ) 
                if(j >> c & 1) ++ cnt; 
            if(cnt <= 1) res += usdp[j]; 
            dp[j] = usdp[j]; 
        }
    }
    cout << res << endl; 
    
}
int main() {
    ios::sync_with_stdio(false); 
    cin.tie(0); 
    cout.tie(0); 
    int ts = 1; 
//     cin >> ts; 
    while(ts -- ) solve(); 
    
    return 0; 
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linuxqq关闭主面板后无法再次打开的问题

文章目录 前言解决方案强调一点 前言 听说QQ出了linux版&#xff0c;所以来试试。结果试试就逝世。这次记录一个关闭后没办法打开的解决办法。 解决方案 刚安装好后如果点了关闭&#xff0c;系统托盘里也没有&#xff0c;点击图标又是重新登录。当然&#xff0c;我们最简单、…

浅谈Linux环境

冯诺依曼体系结构&#xff1a; 绝大多数的计算机都遵守冯诺依曼体系结构 在冯诺依曼体系结构下各个硬件相互配合处理数据并反馈结果给用户 其中控制器和运算器统称为中央处理器&#xff08;CPU&#xff09;&#xff0c;是计算机硬件中最核心的部分&#xff0c;像人类的大脑操控…

钓鱼邮件的发送工具GUI

一.简介 本程序利用Python语言编写&#xff0c;使用Tkinter实现图形化界面&#xff0c;可使用Pyinstaller进行exe打包&#xff0c;程序主界面截图如下&#xff1a; 二.功能 1.支持腾讯企业邮、网易企业邮、阿里企业邮、自建邮服SMTP授权账号&#xff08;其他邮服&#xff0c…

【HTML】交友软件上照片的遮罩是如何做的

笑谈 我不知道大家有没有在夜深人静的时候感受到孤苦难耐&#xff0c;&#x1f436;。于是就去下了一些交友软件来排遣寂寞。可惜的是&#xff0c;有些交友软件真不够意思&#xff0c;连一些漂亮小姐姐的图片都要进行遮罩&#xff0c;完全不考虑兄弟们的感受,&#x1f620;。所…

微信小程序(四十一)wechat-http的使用

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.模块下载 2.模块的使用 在终端输入npm install wechat-http 没有安装成功vue的先看之前的一篇 微信小程序&#xff08;二十&#xff09;Vant组件库的配置- 如果按以上的成功配置出现如下报错先输入以下语句 …

知识价值2-什么是IDE?新手用哪个IDE比较好?

IDE是集成开发环境&#xff08;Integrated Development Environment&#xff09;的缩写&#xff0c;是一种软件应用程序&#xff0c;旨在提供集成的工具集&#xff0c;以方便开发人员进行软件开发。IDE通常包括代码编辑器、编译器、调试器和其他工具&#xff0c;以支持软件开发…

crack实验

资源下载 【免费】crack资源&#xff08;这玩意还要不少于11字&#xff09;资源-CSDN文库 内容 源码 这是一段简单的密码判断程序 流程 exe直接用ida开&#xff08;因该是release的exe&#xff09; 选中分支点直接按空格 此时的va地址是0010106e用动态调试软件调试&#xf…

微信小程序学习指南:从基础知识到代码展示

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

软件实例分享,宠物店兽医电子处方开单系统软件教程

软件实例分享&#xff0c;宠物店兽医电子处方开单系统软件教程 一、软件教程问答 以下教程以 佳易王宠物店兽医电子处方软件V16.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 问&#xff1a;宠物医院电子处方单子使用的纸张大小是多少&…

Screw自动生成数据库文档

Screw简介 官方地址 Screw可以根据数据库中的表自动生成HTML、Word、Markdown格式的文档。 Springboot 3.1集成 生成Springboot项目 Spring Initializr Maven依赖 <dependency><groupId>cn.smallbun.screw</groupId><artifactId>screw-core</…

GPT4:画一只小怪兽,但是不断升级

请你画一只1级的萌怪兽 请你画一只3级的萌怪兽 请你画一只5级的小怪兽 请你画一只10级的小怪兽 请你画一只50级的怪兽 请你画一只100级的怪兽 怪兽被闪电劈了一下&#xff0c;变成了一只0.1级的可爱小怪兽

JAVA-多进程开发-创建等待进程

前言 在项目中&#xff0c;为了实现“并发编程”&#xff08;同时执行多个任务&#xff09;&#xff0c;就引入了“多进程编程”&#xff0c;把一个很大的任务&#xff0c;拆分成若干个很小的任务&#xff0c;创建多个进程&#xff0c;每个进程分别负责其中的一部分任务。 这也…

(三十七)大数据实战——Solr服务的部署安装

前言 Solr是一个基于Apache Lucene的开源搜索平台&#xff0c;它提供了强大的全文搜索、分布式搜索和数据分析功能。Solr 可以用于构建高性能的搜索应用程序&#xff0c;支持从海量数据中快速检索和分析信息。Solr 使用倒排索引和先进的搜索算法&#xff0c;可实现快速而准确的…

NLP快速入门

NLP入门 课程链接&#xff1a;https://www.bilibili.com/video/BV17K4y1W7yb/?p1&vd_source3f265bbf5a1f54aab2155d9cc1250219 参考文档链接1&#xff1a;NLP知识点&#xff1a;Tokenizer分词器 - 掘金 (juejin.cn) 一、分词 分词是什么&#xff1f; 每个字母都有对应…

Codeforces Round 169 (Div. 2)C. Little Girl and Maximum Sum(差分、贪心)

文章目录 题面链接题意题解代码总结 题面 链接 C. Little Girl and Maximum Sum 题意 给q个[l,r]将所有这些区间里面的数相加和最大。 可以进行的操作是任意排列数组 题解 对出现的每个区间内的位置加上1&#xff0c;代表权值 操作完之后求一遍前缀和&#xff0c;得到每个…

《统计学简易速速上手小册》第10章:案例研究和未来趋势(2024 最新版)

文章目录 10.1 统计学成功案例分析10.1.1 基础知识10.1.2 主要案例&#xff1a;药物临床试验10.1.3 拓展案例 1&#xff1a;市场趋势分析10.1.4 拓展案例 2&#xff1a;社会行为研究 10.2 统计学的伦理考量10.2.1 基础知识10.2.2 主要案例&#xff1a;个性化医疗研究10.2.3 拓展…

生活篇——华为手机去除负一屏

华为手机去除如下图的恶心负一屏 打开华为的应用市场app 进入&#xff1a;我的-设置-国家/地区&#xff08;改为俄罗斯&#xff09;-进入智慧助手检查更新并更新智慧助手。 然后重复开始的操作&#xff0c;将地区改回中国&#xff0c;这样就没有负一屏了。

备战蓝桥杯---图论基础理论

图的存储&#xff1a; 1.邻接矩阵&#xff1a; 我们用map[i][j]表示i--->j的边权 2.用vector数组&#xff08;在搜索专题的游戏一题中应用过&#xff09; 3.用邻接表&#xff1a; 下面是用链表实现的基本功能的代码&#xff1a; #include<bits/stdc.h> using nam…

CPU-Z:了解你的电脑硬件的必备工具

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、什么是 CPU-Z&#xff1f;二、下载安装三、…

VueCLI核心知识2:插件、自定义事件

1 插件 功能&#xff1a;增强Vue 1. 定义插件 2. 使用插件 2 自定义事件 一种组件间的通信方式&#xff1a;适用于 子组件 > 父组件 方式1&#xff1a;使用 或者v-on: <template><div id"app"><!-- 1.通过父组件给子组件绑定一个自定义事件实现…