CF1985G D-Function 题解

day11 数位 dp 总结

数位 dp 的定义:所谓数位 dp 也就是根据一个数的每一位来做动态规划,而数位 dp 的题目不会像有些题目,需要你来仔细看需要用到什么算法,而数位 dp 的特点很显著。第一,一般情况下肯定是要往数字每一位数上去考虑的,第二,也就是数据范围,好一点的,可能 n ≤ 1 0 9 n \leq 10 ^ {9} n109 或者 n ≤ 1 0 18 n \leq 10 ^ {18} n1018,狠一点的直接干到 n ≤ 1 0 2000 n \leq 10 ^ {2000} n102000,这样就更加明显了,不可往数字的大小上看,必定得往数字的各个位数上考虑。

例题:

P2657 [SCOI2009] windy 数

题目大致意思:

不含前导零且相邻两个数字之差至少为 2 2 2​ 的正整数被称为 windy 数。windy 想知道,在 a a a​ 和 b b b​ 之间,包括 a a a​ 和 b b b​ ,总共有多少个 windy 数?

题目大致思路:

这道题目很显然数位 dp,毕竟学的就是数位 dp,再接着我们可以想到一个很显然的结论,用数位 dp 处理区间 [ l , r ] [l, r] [l,r] 的区间不好处理,那么我们可以计算出 [ 0 , l − 1 ] [0, l - 1] [0,l1] 的区间和 [ 0 , r ] [0, r] [0,r] 的区间,凭感性理解一下就会得知,答案就是区间到 r r r 的答案减去区间到 l − 1 l - 1 l1 的答案。

接下来就是数位 dp 部分,我使用记忆化搜索的方法来写,当然也可以用递推的方法,我的 dfs 流程如下:

  • d p i , j dp_{i, j} dpi,j 表示数位个数为 i i i,前一位数为 j j j 时,windy 数的个数。

  • 4 4 4 个参数 n o w , l a s t , l a z y , f now, last, lazy, f now,last,lazy,f 来记录,分别表示当前数位个数,上一位数字,是否有前导 0 0 0,以及最高位是否有限制。

  • 首先,我们设定边界,当位数超过,我们当前边界的数位时,显然返回 1 1 1

  • 最高位无限制时,且当前点被记录过,直接可以返回答案,这也就是记忆化。

  • 初始化遍历范围,因为如果最高位有限制,那么我们要找到它最多能遍历到哪里,没有限制显然能够遍历到 9 9 9

  • 遍历, l a s t − i < 2 last - i < 2 lasti<2 也就是数位不满足条件,continue 跳过本次循环,这里及以下的 i i i 表示遍历的数字。

  • 有前导 0 0 0,那么就 l a z y lazy lazy 一直为 1 1 1,继续往下搜,加入答案。

  • 无前导 0 0 0,那么 l a z y lazy lazy 可以变成 0 0 0 l a s t last last 也就可以变成当前遍历的数字 <

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值