题目链接:https://www.luogu.com.cn/problem/P2602

题目大意:

计算区间 \([L,R]\) 范围内 \(0 \sim 9\) 各出现了多少次?

解题思路:

使用 数位DP 进行求解。

定义一个结构体数组 \(f[pos][all0]\) 表示满足如下条件时 \(0 \sim 9\) 出现的次数:

  • 当前所在数位为第 \(pos\) 位;
  • \(all0\) 为 \(1\) 表示当前状态之前一直都是前置 \(0\) ,为 \(0\) 表示前面的数位上面出现过不为 \(0\) 的数。

然后定义一个返回值为此结构体类型的函数 dfs(int pos, int all0, bool limit) 进行求解,其中:

  • \(pos\) 和 \(all0\) 的含义同上;
  • \(limit\) 表示是否处于限制状态。

实现代码如下:

  1. // P2602 [ZJOI2010]数字计数
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. long long cnt[10], pow10[22], num;
  5. int a[22];
  6. struct Node {
  7. long long arr[10];
  8. Node() { memset(arr, 0, sizeof(arr)); }
  9. void merge(Node v) {
  10. for (int i = 0; i < 10; i ++)
  11. arr[i] += v.arr[i];
  12. }
  13. } f[22][2];
  14. bool vis[22][2];
  15. void init() {
  16. pow10[0] = 1;
  17. for (int i = 1; i <= 18; i ++) pow10[i] = pow10[i-1] * 10;
  18. }
  19. Node dfs(int pos, int all0, bool limit) {
  20. if (pos < 0) return Node();
  21. if (!limit && vis[pos][all0]) return f[pos][all0];
  22. int up = limit ? a[pos] : 9;
  23. Node tmp = Node();
  24. for (int i = 0; i <= up; i ++) {
  25. if (i == 0 && all0 && pos>0) ;
  26. else {
  27. if (limit && i==up) tmp.arr[i] += num % pow10[pos] + 1;
  28. else tmp.arr[i] += pow10[pos];
  29. }
  30. tmp.merge(dfs(pos-1, all0&&i==0, limit&&i==up));
  31. }
  32. if (!limit) {
  33. vis[pos][all0] = true;
  34. f[pos][all0] = tmp;
  35. }
  36. return tmp;
  37. }
  38. Node get_num(bool minus1) {
  39. long long x;
  40. cin >> x;
  41. if (minus1) x --;
  42. num = x;
  43. int pos = 0;
  44. while (x) {
  45. a[pos++] = x % 10;
  46. x /= 10;
  47. }
  48. if (num == 0) a[pos++] = 0;
  49. return dfs(pos-1, true, true);
  50. }
  51. int main() {
  52. init();
  53. Node res_l = get_num(true);
  54. Node res_r = get_num(false);
  55. for (int i = 0; i < 10; i ++) {
  56. if (i) putchar(' ');
  57. cout << res_r.arr[i] - res_l.arr[i];
  58. }
  59. cout << endl;
  60. return 0;
  61. }

洛谷P2602 [ZJOI2010]数字计数 题解 数位DP的更多相关文章

  1. 洛谷P2602 [ZJOI2010] 数字计数 (数位DP)

    白嫖的一道省选题...... 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 usin ...

  2. 洛谷P2602 [ZJOI2010]数字计数 题解

    题目描述 输入格式 输出格式 输入输出样例 输入样例 1 99 输出样例 9 20 20 20 20 20 20 20 20 20 说明/提示 数据规模与约定 分析 很裸的一道数位DP的板子 定义f[ ...

  3. 洛谷P2602 [ZJOI2010]数字计数(数位dp)

    数字计数 题目传送门 解题思路 用\(dp[i][j][k]\)来表示长度为\(i\)且以\(j\)为开头的数里\(k\)出现的次数. 则转移方程式为:\(dp[i][j][k] += \sum_{t ...

  4. 洛谷 P2602 [ZJOI2010]数字计数

    洛谷 第一次找规律A了一道紫题,写篇博客纪念一下. 这题很明显是数位dp,但是身为蒟蒻我不会呀,于是就像分块打表水过去. 数据范围是\(10^{12}\),我就\(10^6\)一百万一百万的打表. 于 ...

  5. [洛谷P2602][ZJOI2010]数字计数

    题目大意:求区间$[l,r]$中数字$0\sim9$出现个数 题解:数位$DP$ 卡点:无 C++ Code: #include <cstdio> #include <iostrea ...

  6. 洛谷P2606 [ZJOI2010]排列计数(数位dp)

    题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很 ...

  7. 【洛谷】2602: [ZJOI2010]数字计数【数位DP】

    P2602 [ZJOI2010]数字计数 题目描述 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 输入输出格式 输入格式: 输入文件中仅包含一行两个整数a ...

  8. BZOJ1833或洛谷2602 [ZJOI2010]数字计数

    BZOJ原题链接 洛谷原题链接 又是套记搜模板的时候.. 对\(0\sim 9\)单独统计. 定义\(f[pos][sum]\),即枚举到第\(pos\)位,前面枚举的所有位上是当前要统计的数的个数之 ...

  9. 【洛谷P2602】数字计数

    题目大意:求 [a,b] 中 0-9 分别出现了多少次. 题解:看数据范围应该是一个数位dp. 在 dfs 框架中维护当前的位置和到当前位置一共出现了多少个 \(x,x\in [0,9]\).因此,用 ...

随机推荐

  1. 学习C#泛型

    C#泛型详解 C#菜鸟教程 C#中泛型的使用

  2. selenium webdriver学习(五)------------iframe的处理(转)

    selenium webdriver学习(五)------------iframe的处理 博客分类: Selenium-webdriver 如何定位frame中元素  有时候我们在定位一个页面元素的时 ...

  3. HDU - 6534 Chika and Friendly Pairs

    这个题其实也是很简单的莫队,题目要求是给一个序列,询问l-r区间内部,找到有多少对答案满足 i < j 并且 | a[ i ] -a[ j ] | <=k 也就是有多少对,满足差值小于k的 ...

  4. oracle使用日期

    当使用日期是,需要注意如果有超过5位小数加到日期上, 这个日期会进到下一天! 例如: 1. SELECT TO_DATE(‘01-JAN-93’+.99999) FROM DUAL; Returns: ...

  5. C++ sort使用两个参数来排序

    排序在编程中经常用到,冒泡法排序时间复杂度高,使用C++库函数sort可以快速排序. 1.必须的头文件#include < algorithm>和using namespace std;  ...

  6. 阿里云ECS服务器活动99元一年,最高可买三年

    这几天阿里云 99一年.279三年的服务器活动如火如荼,和之前腾讯三年的服务器非常类似,非常低的价格换取非常高的价值,当然,通常情况下便宜没好货的,想要玩一下的老铁可以进阿里云去看看,阿里云270三年 ...

  7. 原生js实现选字游戏

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. input 的 pattern 验证表单

    pattern 用于定义验证输入正则表达式 pattern 属性适用于以下 <input> 类型:text, search, url, telephone, email 以及 passwo ...

  9. 记前端状态管理库Akita中的一个坑

    记状态管理库Akita中的一个坑 Akita是什么 Akita是一种基于RxJS的状态管理模式,它采用Flux中的多个数据存储和Redux中的不可变更新的思想,以及流数据的概念,来创建可观察的数据存储 ...

  10. H3C 路由优先级