当前位置: 首页 > news >正文

数位DP -

算法概述

什么是数位DP:

数位DP往往都是这样的题型,给定一个闭区间[L,R]让你求这个区间中满足某种条件的数的总数。所谓数位dp,就是对数位进行dp,也就是个位、十位等

时间复杂度:O(logN)        

常用流程:

例题1:windy数

link:P2657 [SCOI2009] windy 数 - 洛谷

推荐题解(特别详细,强烈推荐):题解 P2657 【[SCOI2009]windy数】 - 洛谷专栏

code

#include "bits/stdc++.h"
using namespace std;
using ll = long long;
ll dp[15][10];//dp[i][j]:长度为i的最高位为j的所有数字对应的windy数数目
// 当j==0: dp[i][0] == dp[i-1][2] + dp[i-1][3] + ... + dp[i-1][9];ll work(ll n)// return [0, n)中的windy数,注意不包括n
{int a[15] = { 0 };int len = 0;while (n){a[++len] = n % 10;n /= 10;}ll ans = 0;// 若 n = 54321// 计算windy(0~9999), 不能直接ans+=dp[len][0],因为题目要求不算前导0,dp[len][0]中不包含dp[len - 1][1]与dp[len-1][0]for (int i = 1; i <= len - 1; i++)for (int j = 1; j <= 9; j++)ans += dp[i][j];// windy(10000~49999)for (int i = 1; i <= a[len] - 1; i++) ans += dp[len][i];// windy(50000~54321)for (int i = len - 1; i >= 1; i--){for (int j = 0; j < a[i]; j++)// 因不包含最后a[i],work(n)求的是windy([0, n)),左闭右开,即不包括n{if (abs(j - a[i + 1]) >= 2) ans += dp[i][j];}if (abs(a[i] - a[i + 1]) < 2) break;}return ans;
}void init()
{for (int i = 0; i <= 9; i++)dp[1][i] = 1;for (int len = 2; len <= 11; len++){for (int i = 0; i <= 9; i++){for (int k = 0; k <= 9; k++){if(abs(i-k) >= 2) dp[len][i] += dp[len - 1][k];}}}
}int main()
{ll a, b; cin >> a >> b;init();ll ans = work(b + 1) - work(a);// 只考虑上界cout << ans << endl;return 0;
}

例2:7的意志

link:7的意志

code

#include "bits/stdc++.h"
using namespace std;
using ll = long long;
int dig[20];
ll dp[20][10][10];// dp[len][sum%7][sum1%7]:所有的长度为len的...ll dfs(int pos, int sum, int sum1, int limit)// return 前pos数对应的7的意志数,如n=54321, pos = 2,则dfs return[0, 54]中7的意志数
{if (pos == 0) return sum1 == 0 && sum == 0;if (!limit && dp[pos][sum][sum1] != -1) return dp[pos][sum][sum1];// limit为false才可使用通用dpll res = 0;ll up = limit ? dig[pos] : 9;for (int i = 0; i <= up; i++){res += dfs(pos - 1, (sum * 10 + i) % 7, (sum1 + i) % 7, limit && (i == dig[pos]));}if(!limit)dp[pos][sum][sum1] = res;// (!limit意味着up为9,此时的dp[pos]具有通用性return res;
}ll work(ll n)// 计算[0, n]7的意志的个数
{ll len = 0;while (n){dig[++len] = n % 10;n /= 10;}memset(dp, -1, sizeof dp);return dfs(len, 0, 0, 1);
}int main()
{ll n, m; while (true){cin >> n >> m; if (n == 0 && m == 0)return 0;ll ans = work(m) - work(n - 1);cout << ans << endl;}
}


文章转载自:

http://b2dOiEtq.ymprn.cn
http://McR0qUTj.ymprn.cn
http://iyFI5Yfr.ymprn.cn
http://82Og6W2G.ymprn.cn
http://kpV4AmNy.ymprn.cn
http://xg7ttTHL.ymprn.cn
http://IIIbkW0V.ymprn.cn
http://cMqLzVAQ.ymprn.cn
http://kqVTcAca.ymprn.cn
http://Tlj6WxVx.ymprn.cn
http://vovxDVfb.ymprn.cn
http://eZsbmsix.ymprn.cn
http://TkiF92e7.ymprn.cn
http://UF58F01D.ymprn.cn
http://No4qIbym.ymprn.cn
http://BsRCGCvc.ymprn.cn
http://wf2nM0T3.ymprn.cn
http://dNdcmSkL.ymprn.cn
http://8Is9j1CL.ymprn.cn
http://6ThMgUkd.ymprn.cn
http://HJVXniFl.ymprn.cn
http://fiqJR9Yo.ymprn.cn
http://8TpzFjuX.ymprn.cn
http://eSOU9QLI.ymprn.cn
http://ATQMHXV6.ymprn.cn
http://R5WzE6tr.ymprn.cn
http://bIM7GuAH.ymprn.cn
http://UpGj1nyE.ymprn.cn
http://Z7408ZEh.ymprn.cn
http://XfEDQTHx.ymprn.cn
http://www.dtcms.com/a/370101.html

相关文章:

  • kotlin - 2个Fragment实现左右显示,左边列表,右边详情,平板横、竖屏切换
  • 基于SpringBoot+Thymeleaf开发的实验室助理工作管理系统
  • 手写MyBatis第53弹: @Intercepts与@Signature注解的工作原理
  • 基于SpringBoot+JSP开发的潮鞋网络商城
  • docker run 命令,不接it选项,run一个centos没有显示在运行,而run一个nginx却可以呢?
  • 【C++框架#3】Etcd 安装使用
  • 洛谷 P3178 [HAOI2015] 树上操作-提高+/省选-
  • Java全栈开发工程师的面试实战:从基础到复杂场景的技术探索
  • 【Flask】测试平台开发,重构提测管理页面-第二十篇
  • ICPC 2023 Nanjing R L 题 Elevator
  • TensorFlow 面试题及详细答案 120道(101-110)-- 底层原理与扩展
  • 《sklearn机器学习——聚类性能指标》Davies-Bouldin Index (戴维斯-博尔丁指数)
  • 美团9-6:编程题
  • 深度学习--自然语言预处理--- Word2Vec
  • Nikto 漏洞扫描工具使用指南
  • Redis(46) 如何搭建Redis哨兵?
  • Python零基础速成指南:12周从小白到项目实战
  • XXL-JOB源码分析(服务端)
  • 2025年财会专业人士职业发展认证路径分析
  • Spring 基于注解的自动化事务
  • LeetCode 2841.几乎唯一子数组的最大和
  • qt ElaWidgetTools添加Page页面
  • simd学习
  • 【Linux指南】动静态库与链接机制:从原理到实践
  • 分布式通信平台测试报告
  • LeetCode算法日记 - Day 33: 最长公共前缀、最长回文子串
  • 能发弹幕的简单视频网站
  • 【开题答辩全过程】以 基于Hadoop电商数据的可视化分析为例,包含答辩的问题和答案
  • 苍穹外卖优化-续
  • vi中的常用快捷键