简介 数位DP是一类非常精巧的动态规划,它解决的问题是(0,r]区间上满足某种性质的数的计数问题。例如,求(0,468]中数位中没有”49”的数的个数。动态规划的关键是找到重叠子问题和最优子结构,为此数位DP将区间的右端点r看作是字符串,例如468被当做”468”处理。显然468是个3位数,比这个数小的数有, 000 001 ⋯⋯ 099100101⋯⋯199200201⋯⋯299300301⋯⋯399400401⋯⋯469 显然,如果我们能够逐段求出答案就可以找到最终答案。如何巧妙地组织这个解空间,然后逐步求解呢? 可以按照下图组织: 上图中存在比较多的重叠子问题,可以使用动态规划来解决;需要特别强调的是如果百位为4或者百位为4且十位为6的时候,其对应的子问题,不具有通用性,不应该备忘。上述条件被称为limit条件。 引入 请计算[0,234]中不包含49的数字的个数。 如何求解这个问题呢? 首先看百位上的情况,百位一定是受限制的,其数值只能取0到4,而不是0到9。我们来考虑百位为0、1的情况,只需计算000到099中不包行49的数的个数就好了;当考虑百位为2时,情况变得复杂起来,其十位只能考虑0、1、2、3,而非0到9。百位为0、1不满足limit条件,其对应的子问题(00到99中不含49的数)有一定的通用性需要记录,以便复用。 上代码 #include<map> #include<vector> #include<unordered_set> #include<unordered_map> #include<list> #include<queue> #include<deque> #include<stack> #include<iostream> #include<set> using namespace std; const int MAX_LEN = sizeof(int) / sizeof(char) * 8; class Solution { public: Solution(int x) { this->x = x; memset(dp, (char)(-1), sizeof(dp)); } int work() { string d = this->init(); return this->dfs((int)d.size() - 1, d, true, 0); } private: string init() { string d; int x = this->x; while (x) { int tmp = x % 10; x /= 10; d.push_back(tmp); } return d; } int dfs(int pos, string& d, bool limit, int state) { if (pos == -1) { if (state == 49) { return 1; } else { return 0; } } if (!limit && dp[pos][state] != -1) return dp[pos][state]; int maxNum = limit ? d[pos] : 9; int cnt = 0; for (int dNum = 0; dNum <= maxNum; ++dNum) { if (state == 4 && dNum == 9) { cnt += dfs(pos - 1, d, limit&&d[pos]==dNum, 49); } else if (state == 49) { cnt += dfs(pos - 1, d, limit&&d[pos]==dNum, 49); } else { cnt += dfs(pos - 1, d, limit&&d[pos]==dNum, dNum == 4 ? 4 : 0); } } if (!limit) { dp[pos][state] = cnt; } return cnt; } int x; int dp[MAX_LEN][2]; }; int main() { int x; cin>>x; Solution s(x); cout<<"result:\t"; cout<<s.work()<<endl; return 0; } 确定要放弃本次机会? 福利倒计时 : : 立减 ¥ 普通VIP年卡可用 立即使用 GavinAlgorithm 关注 关注 1 点赞 踩 1 收藏 觉得还不错? 一键收藏 知道了 0 评论 分享 复制链接 分享到 QQ 分享到新浪微博 扫一扫 举报 举报 专栏目录 数位dp专题 hipamp的博客 01-13 648 前言 本篇博客目的是给自己总结复习用,而不是给萌新学习用滴。萌新能不能看得懂需要看造化=.=,毕竟数位 dpdpdp 还是有点难理解的。 概括 数位 dpdpdp,是用来解决一些带有数位上的限制的计数问题的。常见的有问区间 [L,R][L, R][L,R] 中满足某种数位限制的数的个数,或者求数对的对数等等,也可以用来求和。一般是用 [0,R][0,R][0,R] 的 值减去 [0,L−1][0, L- 1][0,L−1] 的值。 常常设 dp[pos][sta]dp[pos][sta]dp[pos][st 数位DP专题:经典题 LC233.数字1的个数 qq_52143141的博客 01-02 291 本题是力扣水hard,直接上数位dp加一些预处理就能AC 该题比较简单,作为数位dp的入门题,重要的是dp的递推树,而预处理部分往往是这些题中思考的难点第一次写分享,如有写的不明白的地方评论区留言,我必及时回复😎。 参与评论 您还未登录,请先 登录 后发表或查看评论 【数位DP】专题 fisty 06-11 2456 所谓数位DP就是基于考虑数字的每一位来转移的DP。 例如求比456小的数,可以这么考虑, 4 5 6 4 5 (0~6) 4 (0~4) (0~9) (0~3)(0~9) (0~9) 数位DP专题小结--by sgx Mr.Phoebe的专栏 08-08 1950 数位DP,一句话概括,就是在一个给定区间内求出满足某中奇葩条件的数字个数,这真是奇葩题目,但是总体写起来又有一定规律性。 主要可以分为以下几个步骤: 确定主体框架,确定一个大方向,想想该如何设计状态; 下面基本就是模板,直接DFS就行了,一位一位处理,这也是他叫按位DP的原因。 数位DP代码一般都很短,不过效率挺好,解决一些竞赛中出现的问题非常有用 。 如果看了这部分 ,你感觉还 数位dp 专题 weixin_30433075的博客 07-30 117 数位dp 专题 先来模板: int dfs(int i,int s,bool e) ///枚举第i位,第i位前一位的数字为s,e表示前缀是否已达到上界。(如果未达到,则枚举0000...~9999..,反之枚举0000...~abcd...) { if(i==-1) return 1; if(!e&&~f[i][s]) return f[i][s]... 数位DP专题 qq_41925919的博客 01-15 419 A - Beautiful numbers CodeForces - 55D 对于美丽的数的定义是这样的:一个数可以被它的每一个非零数位的数所整除,就位美丽的数。给你【li,ri】,让你算出这个范围中美丽的数有多少个? 解: 我们只需要判断这个数能不能被每个非零位数的总最小公倍数整除即可; 1-9的最小公倍数为2520,我们可以把范围给缩小到2520; 但是2520的三维数组还是太大了,我们还可以... kuangbin专题 概率/期望DP总结 mzip的博客 05-26 483 题目链接: https://vjudge.net/contest/76505#overview A- A Dangerous Maze LightOJ - 1027 题意: 现在在你面前有N个门。每个门要么把你传送出迷宫,要么把你传送来的位置且你的记忆也会回到初始的时候。现在给出每个门传送的时间t,若t为正数,说明该门花费时间t可以将你传送出迷宫,若 t 为负数,说明该门花费时间 t 将你传送... DP优化专题 playedgames的博客 08-15 955 倍增优化DP,数据结构优化DP,单调队列优化DP,斜率优化DP,四边形不等式优化DP DP专题-算法盲点扫荡:状压 DP Plozia 的小窝 06-04 365 DP专题-算法盲点扫荡:状压 DP1. 前言2. 题单[P2396 yyy loves Maths VII](https://www.luogu.com.cn/problem/P2396)[P2150 [NOI2015] 寿司晚宴](https://www.luogu.com.cn/problem/P2150)3. 总结 1. 前言 本文是作者写的第 3 篇状压 DP 的博文,专门用来总结、复习状压 DP 这一动态规划的相关内容。 DP专题-学习笔记:状压 DP(2021/3/2) DP专题-专项训练:状 数位DP.pdf 07-12 数位DP整理的模板和一些题目的题解。QAQ没钱下载资源了只好上传点东西。 数位DP入门 08-22 数位DP入门思想,包括详细的思考过程以及一些习题的讲解 动态规划之数位DP专题(附题目清单) 剑锋OI SharpSwordOI 12-14 811 动态规划之数位DP专题 数位dp qq_17175221的博客 04-30 249 数位dp:/*数位dp模板 int dfs(int i, int s, bool e) { if (i==-1) return s==target_s; if (!e && ~f[i][s]) return f[i][s]; int res = 0; int u = e?num[i]:9; for (int d = first?1:0; d ... kuangbin专题十五数位dp总结 qq_34921856的博客 04-05 499 这里是一篇讲数位dp的文章 数位dp最重要的就是状态的建立! A - Beautiful numbers 一道数位dp的好题。 不过理清思路后也挺好理解的。 题目要求求能被它所有位数整除的数的个数,换句话说就是能被它所有位数的lcm整数的数的个数,所以我们得维护一个lcm。又因为a%p=a%(k*p)%p。所以我们可以先将所有的数模上lcm(1,2,3…9),然后在最后再判断模lcm是... hdu5787 数位dp 数位压缩 JIBANCANYANG 08-03 626 分析: 大概是比较经典的数位dp,需要维护连续的kk个数字不相同,所以我们的状态记录里需要记录前k−1k-1个数字是哪些,扩展下一位的时候不能出现前k−1k-1位的数字。 这样就来设计状态:dp[len][k][ban]dp[len][k][ban],表示前长度为lenlen,连续的kk个字符禁止出现相同,前k−1k-1个数字为banban。 这里的banban用了数字压缩的技巧,比如前33个 数位 DP详解 zhy_Learn的博客 12-03 769 原文:https://www.cnblogs.com/itlqs/p/5935308.html 数位DP其实是很灵活的,所以一定不要奢求一篇文章就会遍所有数位DP的题,这一篇只能是讲清楚一种情况,其他情况遇到再总结,在不断总结中慢慢体会这个思想,以后说不定就能达到一看到题目就能灵活运用的水平。(其实DP都是这样……) 这一篇要说的数位DP是一道最简单的数位DP:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题目大意:多组数据,每次给定区间[n,m],求在n到m 数位dp总结 之 从入门到模板 热门推荐 努力 08-03 7万+ for(int i=le;i<=ri;i++) if(right(i)) ans++; 基础篇 数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数。所谓数位dp,字面意思就是在数位上进行dp咯。数位还算是比较好听的名字,数位的含义:一个数有个位、十位、百位、千位......数的每一位就是数位啦! 之所以要引入数位的概念完全就是为了dp。 数位DP入门解析与应用实例 "数位DP入门PPT的参考文献和相关问题解析" 数位DP,全称为数字动态规划(Digital Dynamic Programming),是一种在处理与数字相关的动态规划问题时使用的技巧。它通常涉及到对数字的每一位进行操作,通过预处理和... 评论 被折叠的 条评论 为什么被折叠? 到【灌水乐园】发言 查看更多评论 添加红包 祝福语 请填写红包祝福语或标题 红包数量 个 红包个数最小为10个 红包总金额 元 红包金额最低5元 余额支付 当前余额3.43元 前往充值 > 需支付:10.00元 取消 确定 下一步 知道了 成就一亿技术人! hope_wisdom 发出的红包 实付元 使用余额支付 点击重新获取 扫码支付 钱包余额 0 抵扣说明: 1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。 余额充值