动态规划——数位DP 学习笔记

这篇具有很好参考价值的文章主要介绍了动态规划——数位DP 学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

动态规划——数位DP 学习笔记

定义

引入

数位 DP 往往都是这样的题型:给定一个区间 \([l, r]\),求这个区间中满足某种条件的数的总数。

简单的暴力代码如下:

int ans = 0;
for(int i = l; i <= r; ++i)
    if(check(i)) ++ans;

而当数据规模过大,暴力枚举就 \(\mathbb T\) 飞了,因此引入数位 DP:

概念

数位(digit):对于十进制,即把一个数字按照个位、十位、百位等,一位一位地拆开,它每一位上的数字,也就是 \(0 \sim 9\);其他进制可类比十进制。

数位 DP:一种按照数位暴力枚举的方式,用来解决一类特定问题;这种问题比较好辨认,一般具有这几个特征:

  1. 提供一个数字区间(有时也只提供上界)来作为统计的限制;
  2. 统计满足某种条件的数的数量,有时也有统计总和、平方和等的;
  3. 上界很大,甚至会有 \(10^{18}\) 这么大,暴力枚举验证会超时;
  4. 这些条件经过转化后可以使用「数位」的思想去理解和判断。

原理

例如,当我们在数数的过程中,\(100 \sim 199\)\(200 \sim 299\) 这两部分,后两位是完全相同的,这种重复计算可以通过 DP 的方式进行优化。

实现

计数原理

数位 DP 中通常会利用常规计数问题技巧,比如把一个区间内的答案拆成两部分相减,即查分的思路:

$ans_{[l, r]} = s_r - s_{l - 1}$.

一般根据是否计入 \(0\) 的贡献,将 \(s_k\) 定义为:\(\sum[0, k]\)\(\sum[1, k]\).

数的存储

一般将数字中较低位存在数组的低位之中,即:

typedef long long ll;
ll solve(ll x) {
    int len = 0;
    while (x) a[++len] = x % 10, x /= 10;
    return dfs(...); //记忆化搜索
}

常用形参

统计答案可以选择记忆化搜索,也可以选择循环迭代递推;因为数位 DP 的预处理一般比较变态,所有我一般使用记忆化搜索。

常用的形式参数如下:

  1. pos(int):表示当前枚举的位置,一般从 \(\mathrm{len}\) 开始,到 \(0\) 为止。
  2. limit(bool):表示当前枚举到的位置,可以填的数是否收到限制;若为 true,则该位最大填 \(a_{pos}\);否则最大填 \(R-1\),其中 \(R\) 表示枚举的进制数。
  3. sum(int):表示从 \(\mathrm{len}\)\(pos + 1\) 位的贡献,常用的有求和等。
  4. last(int):表示上一位填的数,当题目限制连续的两个(或多个)数位有条件限制的话常用。
  5. lead0(bool):表示从 \(\mathrm{len}\)\(pos + 1\) 是否都为 \(0\)(前导零)。
  6. r(int):表示从 \(\mathrm{len}\)\(pos + 1\) 这个前缀模一个数 \(\bmod\) 的结果,也可以表示数位和取模的结果。
  7. st(bool):常用与状态压缩,其二进制表示某一位是否满足某一条件等。

如何复用结果

简单分析可知,一定是已经求解过中,状态与当前状态相同的,可以复用,如 possumlast 相同等;特殊的,当 limit == 1lead0 == 1 时,即当前位受到限制时,无需记录状态,因为这一状态不会频繁的复用,这种空间换时间价值不大。

即:

typedef long long ll;
ll f[N][M]; // DP 数组,第一维表示枚举到的数位,第二维表示当前的状态;默认为 -1
ll dfs(int pos, bool limit, int sum) {
    if (!pos) return sum;
    if (!limit && f[pos][sum] != -1) return f[pos][sum];
    int up = limit ? a[pos] : 9;
    ll res = 0; for (int i = 0; i <= up; ++i)
        res = (res + dfs(pos - 1, limit && i == up, sum + i)) % MOD;
    if (!limit) f[pos][sum] = res;
    return res;
}

习题

见:https://www.luogu.com.cn/training/384691

Reference

[1] https://oi-wiki.org/dp/number/
[2] https://blog.csdn.net/hzf0701/article/details/116717851
[3] https://blog.csdn.net/m0_63726942/article/details/127060217文章来源地址https://www.toymoban.com/news/detail-710446.html

到了这里,关于动态规划——数位DP 学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 动态规划——树形DP 学习笔记

    前置知识:树基础。 树形 DP,即在树上进行的 DP,最常见的状态表示为 (f_{u,cdots}) ,表示以 (u) 为根的子树的某个东东。 本文将讲解一些经典题目(树的子树个数、树的最大独立集、树的最小点覆盖、树的最小支配集、树的直径、树的重心、树的中心),以及一些常见形

    2024年02月08日
    浏览(10)
  • 动态规划——状压DP 学习笔记

    前置知识:位运算 动态规划的过程是随着阶段的增长,在每个状态维度上不断扩展的。 在任意时刻,已经求出最优解的状态与尚未求出最优解的状态在各维度上的分界点组成了 DP 扩展的“轮廓”。对于某些问题,我们需要在动态规划的“状态”中记录一个集合,保存这个“

    2024年02月08日
    浏览(11)
  • 动态规划——区间DP 学习笔记

    不含四边形不等式优化。 线性动态规划的局限性在于,它只能顺推或倒退,而不能有子区间依赖的问题。 区间动态规划是线性动态规划的扩展,它将问题划分为若干个子区间,并通过定义状态和状态转移方程来求解每个子区间的最优解,最终得到整个区间的最优解。 区间动

    2024年02月08日
    浏览(11)
  • 动态规划——矩阵优化DP 学习笔记

    前置知识:矩阵、矩阵乘法。 斐波那契数列 在斐波那契数列当中, (f_1 = f_2 = 1) , (f_i = f_{i - 1} + f_{i - 2}) ,求 (f_n) 。 而分析式子可以知道,求 (f_k) 仅与 (f_{k - 1}) 和 (f_{k - 2}) 有关; 所以我们设矩阵 (F_i = begin{bmatrix} f_{i - 1} f_{i - 2} end{bmatrix}) 。 设矩阵 (text{Ba

    2024年02月08日
    浏览(12)
  • 动态规划——斜率优化DP 学习笔记

    动态规划——斜率优化DP 学习笔记

    适用于求解最优解(最大、最小)问题。 可以将转移方程可以化为 (left[begin{array}{rl} 仅与 space i space 有关 是我们想要最大/最小化的 \\\\ 仅与 space j space 有关 是已知的 \\\\ 与 space i space 和 space j space 都有关 是两项相乘 end{array}right]) 三部分的, 都可以考虑用斜率优化

    2024年02月08日
    浏览(12)
  • 「学习笔记」数位 DP

    意义不大的题不写了。 点击查看目录 目录 「学习笔记」数位 DP 概述 例题 P2657 [SCOI2009] windy 数 思路 代码 P4317 花神的数论题 思路 P4124 [CQOI2016]手机号码 思路 代码 haha数 题意 思路 代码 0和1的熟练 题意 思路 代码 苍与红的试炼 题意 思路 代码 数位 DP 一般用来解决「在一个较

    2023年04月09日
    浏览(6)
  • 动态规划——决策单调性优化DP 学习笔记

    动态规划——决策单调性优化DP 学习笔记

    对于最优性问题,常有状态转移方程: (f_i = min/max{f_jdots}) , 形象的:如果 (i) 的最优转移点是 (j) , (i\\\') 的最优转移点是 (j\\\') ,当 (ii\\\') 时,有 (jle j\\\') ,则称该 DP 问题具有决策单调性。 即: (i) 单增,其最优转移点单调不减。 如何发现一个转移方程具有决策

    2024年02月08日
    浏览(14)
  • 动态规划——带权二分优化DP 学习笔记

    动态规划——带权二分优化DP 学习笔记

    带权二分其实并不一定用于优化 DP,也可能用于优化贪心等最优化的算法。 带权二分也叫 WQS 二分,最初由王钦石在他的 2012 年国家集训队论文中提出。 使用情况 要解决一个最优化问题(求最大 / 最小值) 有一个限制,一般是某个参数要求一定恰好为 (k) 而带权二分就可以

    2024年02月08日
    浏览(12)
  • AcWing算法学习笔记:动态规划(背包 + 线性dp + 区间dp + 计数dp + 状态压缩dp + 树形dp + 记忆化搜索)

    AcWing算法学习笔记:动态规划(背包 + 线性dp + 区间dp + 计数dp + 状态压缩dp + 树形dp + 记忆化搜索)

    算法 复杂度 时间复杂度0(nm) 空间复杂度0(nv) 代码 算法 通过滚动数组对01背包朴素版进行空间上的优化 f[i] 与 f[i - 1]轮流交替 若体积从小到大进行遍历,当更新f[i, j]时,f[i - 1, j - vi] 已经在更新f[i, j - vi]时被更新了 因此体积需要从大到小进行遍历,当更新f[i, j]时,f[i - 1,

    2024年02月21日
    浏览(8)
  • 动态规划(DP)(算法笔记)

    动态规划(DP)(算法笔记)

    本文内容基于《算法笔记》和官方配套练题网站“晴问算法”,是我作为小白的学习记录,如有错误还请体谅,可以留下您的宝贵意见,不胜感激。 动态规划(Dynamic Programming,DP)是一种用来解决一类最优化问题的算法思想。简单来说,动态规划将一个复杂的问题分解成若干个子

    2024年02月05日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包