Day 15 - 数位 DP 与状压 DP
1|0数位 DP
下面将简要介绍数位
1|1引入
数位是指把一个数字按照个、十、百、千等等一位一位地拆开,关注它每一位上的数字。如果拆的是十进制数,那么每一位数字都是
数位
-
要求统计满足一定条件的数的数量(即,最终目的为计数);
-
这些条件经过转化后可以使用「数位」的思想去理解和判断;
-
输入会提供一个数字区间(有时也只提供上界)来作为统计的限制;
-
上界很大(比如
),暴力枚举验证会超时。
数位
考虑人类计数的方式,最朴素的计数就是从小到大开始依次加一。但我们发现对于位数比较多的数,这样的过程中有许多重复的部分。例如,从
数位
那么有了通用答案数组,接下来就是统计答案。统计答案可以选择记忆化搜索,也可以选择循环迭代递推。为了不重不漏地统计所有不超过上限的答案,要从高到低枚举每一位,再考虑每一位都可以填哪些数字,最后利用通用答案数组统计答案。
接下来我们具体看几道题目。
1|2例题一
例 1 Luogu P2602 数字计数。
题目大意:给定两个正整数
方法一
解释
发现对于满
有了
实现
参考代码:
方法二
解释
此题也可以使用记忆化搜索。
详见代码注释
过程
参考代码:
1|3例题二
例 2 HDU 2089 不要 62。
题面大意:统计一个区间内数位上不能有 4 也不能有连续的 62 的数有多少。
解释
没有 4 的话在枚举的时候判断一下,不枚举 4 就可以保证状态合法了,所以这个约束没有记忆化的必要,而对于 62 的话,涉及到两位,当前一位是 6 或者不是 6 这两种不同情况计数是不相同的,所以要用状态来记录不同的方案数。
实现
参考代码:
1|4例题三
例 3 SCOI2009 windy 数。
题目大意:给定一个区间
解释
首先我们将问题转化成更加简单的形式。设
对于一个小于
有了这个性质,我们可以定义
写出 状态转移方程:
这里的
我们发现,尽管前缀所选择的状态不同,而
实现
参考代码:
1|5例题四
例 4.SPOJMYQ10。
题面大意:假如手写下
解释
注:由于这里考虑到的镜像,只有
首先,在数位
其次,由于数值超过 long long 范围,所以
镜像解决了,如何判断回文?
我们需要用一个小数组记录一下之前的值。在未超过一半的长度时,只要不超上限就行;在超过一半的长度时,还需要判断是否和与之「镜面对称」的位相等。
需要额外注意的是,这道题的记忆化部分,不能用 memset
,否则会导致超时。
实现
参考代码:
1|6例题五
例 5.P3311 数数。
题面:我们称一个正整数
解释
阅读题面发现,如果将数字看成字符串,那么这就是需要完成一个多模匹配,自然而然就想到
设
至于题目中的「不包含」条件,只需在
转移很好想,详见代码主函数部分。
实现
参考代码:
此题可以很好地帮助理解数位
1|7习题
2|0状压 DP
2|1定义
状压
2|2例题 1
在
国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共
解释
设
对于编号为
设当前行的状态为
设上一行的状态编号为
实现
参考代码:
2|3例题 2
有
解释
我们用
需要注意的是这里不能直接枚举集合再判断是否为子集,而应使用子集枚举,从而使时间复杂度为
实现
参考代码:
2|4习题
__EOF__

本文链接:https://www.cnblogs.com/So-noSlack/p/18315291.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文来自博客园,作者:So_noSlack,转载请注明原文链接:https://www.cnblogs.com/So-noSlack/p/18315291
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)