news 2026/2/17 10:02:16

数位dp模版

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数位dp模版

直接放一篇比较有代表性的数位dp学习的题目链接和标准的题解代码,由于题解代码较少就懒得解释更多了,关键就是从高位到低位的状态dfs➕记忆化➕对区间答案拆解为前缀差

https://www.luogu.com.cn/problem/P13085

#include <iostream> #include <vector> #include <cmath> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; // dp[pos][pre] // pos: 当前处理到的位数 // pre: 上一位填写的数字 (0-9) // 因为 pre 有可能是前导零状态或者初始状态,我们在记忆化时通常只记录 lead=false 的情况 ll dp[20][15]; int a[20]; // 存储把数字拆解后的每一位 // dfs 函数 // pos: 当前位数 // pre: 上一位数字 // lead: 是否处于前导零状态 (true 表示前面全是 0) // limit: 最高位限制 (true 表示当前位受原数限制) ll dfs(int pos, int pre, bool lead, bool limit) { // 递归边界:填完了所有位,说明找到了一种合法方案,返回 1 if (pos == 0) return 1; // 记忆化搜索: // 如果没有最高位限制,且不是前导零状态,且该状态已经计算过,直接返回 if (!limit && !lead && dp[pos][pre] != -1) return dp[pos][pre]; // 当前这一位能填的最大数字 // 如果受 limit 限制,只能填到 a[pos];否则能填到 9 int up = limit ? a[pos] : 9; ll ans = 0; // 枚举当前位可能填的所有数字 i for (int i = 0; i <= up; i++) { // 判断当前填的 i 是否合法 // 情况 1: 之前全是前导零 if (lead) { if (i == 0) { // 如果当前继续填 0,则继续保持前导零状态,pre 不更新(或者传个特殊值,这里习惯用-2代表无前驱) // limit 更新:如果本来受限且当前填了上限(0==up),则继续受限 ans += dfs(pos - 1, -2, true, limit && (i == up)); } else { // 如果当前填了非 0,前导零状态结束。 // 因为是第一位有效数字,不需要和上一位比较差值,直接合法 ans += dfs(pos - 1, i, false, limit && (i == up)); } } // 情况 2: 之前已经有有效数字了 else { // 必须满足题目条件:相邻数字之差 >= 2 if (abs(i - pre) >= 2) { ans += dfs(pos - 1, i, false, limit && (i == up)); } } } // 记录状态(仅在无限制且非前导零时记录,因为 limit 和 lead 特殊情况复用率低) if (!limit && !lead) dp[pos][pre] = ans; return ans; } // 计算 [1, x] 之间的 Windy 数 ll solve(ll x) { int len = 0; // 把数字 x 拆解存入数组,比如 123 -> a[3]=1, a[2]=2, a[1]=3 while (x) { a[++len] = x % 10; x /= 10; } // 记忆化数组初始化为 -1 // 注意:如果是多次询问,且 dp 状态与 limit/lead 无关,其实 dp 数组只需要 memset 一次。 // 但为了保险和逻辑简单,这里每次 solve 都清空(实际上这题 dp 数组可以复用,放在全局只初始化一次更优) // 本题数据量较小,每次初始化也没问题,若 TLE 可移到 main 函数外 memset(dp, -1, sizeof(dp)); // 从最高位 len 开始搜,pre 初始设为 -2(一个不可能干扰 0-9 判断的数) return dfs(len, -2, true, true); } int main() { ll a, b; cin >> a >> b; // 答案是 [1, b] 的数量 减去 [1, a-1] 的数量 cout << solve(b) - solve(a - 1) << endl; return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/14 11:17:50

2026年了,AI对游戏行业“渗透”到什么程度了?

2025年年末&#xff0c;有很多人提问&#xff1a;“你认为AI究竟是真革命还是假繁荣&#xff1f;”有高赞回答写道&#xff1a;“第一反应是想笑&#xff0c;这就像1998年问互联网是不是骗局&#xff0c;或者2010年问移动互联网是不是伪需求……”从ChatGPT在2023年春爆火&…

作者头像 李华
网站建设 2026/2/8 14:01:16

什么是一个传递函数的“中频增益”?它和将传递函数化为“尾一标准型”后得到的系数K是一个东西吗?

什么是一个传递函数的“中频增益”&#xff1f;它和将传递函数化为“尾一标准型”后得到的系数K是一个东西吗&#xff1f;要搞清楚 “中频增益” 和 “尾一标准型” 系数 K 的关系&#xff0c;我们需要从定义、物理意义、计算方式三个维度拆解&#xff0c;结论先行&#xff1a;…

作者头像 李华
网站建设 2026/2/15 11:47:17

SpringBoot+Vue Spring boot名城小区物业管理系统管理平台源码【适合毕设/课设/学习】Java+MySQL

摘要 随着城市化进程的加速&#xff0c;小区物业管理系统的智能化需求日益增长。传统物业管理模式依赖人工操作&#xff0c;存在效率低、信息不透明、服务响应慢等问题。为提高物业管理效率、优化业主体验&#xff0c;基于信息技术的物业管理系统成为研究热点。该系统通过数字化…

作者头像 李华
网站建设 2026/2/13 20:44:30

SpringBoot+Vue 小学生身体素质测评管理系统管理平台源码【适合毕设/课设/学习】Java+MySQL

摘要 随着素质教育的全面推进&#xff0c;小学生身体素质测评已成为学校教育管理的重要组成部分。传统纸质记录和人工统计方式效率低下&#xff0c;容易出现数据错误和丢失问题&#xff0c;难以满足现代教育信息化管理的需求。针对这一现状&#xff0c;开发一套数字化、智能化…

作者头像 李华
网站建设 2026/2/14 19:08:08

基于LSSVM多输出回归+SHAP可解释性分析 Matlab代码(多输入多输出)

目录 1、代码简介 2、代码运行结果展示 3、代码获取 1、代码简介 (LSSVMSHAP)基于最小二乘向量机的数据多输入多输出SHAP可解释性分析的回归预测模型 1、在机器学习和深度学习领域&#xff0c;模型复杂度的不断攀升使得决策过程的可解释性成为研究热点。模型如何做出决策、…

作者头像 李华
网站建设 2026/2/16 5:29:52

提示工程架构师必收藏:模块化设计资源大全

提示工程架构师必收藏&#xff1a;模块化设计资源大全 关键词&#xff1a;提示工程、模块化设计、架构师、资源整合、设计模式、代码结构、应用场景 摘要&#xff1a;本文专为提示工程架构师打造&#xff0c;全面深入地介绍模块化设计相关内容。首先阐述模块化设计在提示工程…

作者头像 李华