题目

给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。

数位DP

(1)分情况,逐位讨论。

(2)模型:计算在[L,R]中有多少个数满足条件。

(3)套路:将问题转化为[1,R]-[1,L-1],只需回答[1,X]的询问即可。

思路

1.算出[1,X]:

(1)按位拆分,为后面做铺垫

(2)预处理:

	 1)pow[]表示10的次幂

	 2)f[]表示:后i位自由的话每个数字出现的次数

ps:有一个规律。0~9每个数字出现1次,10~99出现20次,100~999出现300次。出现次数为:n*10^(n-1)(n为位数)

(3)处理比X少一位的情况

 从0~9共10个数。同位数计算10次,加上pow[i-1]即可。

(4)处理全部位数

	从最高位到最低位。比如ABCDE,A会出现BCDE+1次,以此类推。

2.将第一遍算出的答案全部*(-1),就相当于减去。

#include<iostream>
using namespace std;
long long ans[10],f[20],pow[20];
int p[20],l;
void deal(long long x, long long y){ // 统计固定位是x,自由位有y个的情况
for(long long i=0;i<10;i++) ans[i]+=f[y]; // 算后面的
for(long long p=x;p;p/=10) ans[p%10]+=pow[y]; // 算前面的
}
void calc(long long x){
if(!x) return;
l=0,pow[0]=1;
for(long long tp=x;tp;tp/=10) p[++l]=tp%10; // 一位一位拆分
for(int i=1;i<=l;i++) pow[i]=pow[i-1]*10; // 10的次幂
for(int i=1;i<=l;i++) f[i]=pow[i-1]*i; // 后i位是自由的话,每个数字出现多少次
// 处理比l小位数的情况
for(int i=1;i<l;i++) // 枚举,当前是i位数
for(int k=1;k<10;k++) deal(k,i-1); // 枚举这个i位数,是以k开头的
// 处理l位数的情况
// i : 当前算到哪个位置
// lst : 当前前面的数是多少
// st,en : 数字的枚举范围
for(long long i=l,lst=0,st,en;i;lst+=p[i--]){
st=(i==l)? 1:0;//如果i==l,则这是最高位,不能是0
en=(i==1)? p[i]:p[i]-1;//
lst *= 10;
for(int k = st; k <= en;k++) deal(lst+k, i-1);
}
}
int main(){
long long a,b;
cin>>a>>b;
calc(a-1);
for(int i=0;i<10;i++) ans[i]*=-1;
calc(b);
for(int i=0;i<10;i++) cout<<ans[i]<<" ";
return 0;
}

欢迎指正评论O(∩_∩)O~~

【数位DP】数字统计的更多相关文章

  1. 【hdu4734】【F(x)】数位dp + 小小的总结一下

    (https://www.pixiv.net/member_illust.php?mode=medium&illust_id=65608478) Problem Description For ...

  2. zznu 1255 数字统计(数位DP, 数学方法)

    最近在学数位DP, 感觉还是满有收获的! 做了几个题之后想起来自己OJ上曾经做的一道题,以前是用数学方法写的,现在改用数位DP来写了一遍. 题目: 1255: 数字统计 时间限制: 1 Sec  内存 ...

  3. 数字统计类题目的非数位DP解法

    ZJOI2010 数字统计 上题题意为求[l,r]区间中每个数字(0~9)出现的次数 一般的做法为将区间当成[0,r]-[0,l-1],然后进行数位DP 但事实上将区间当成[0,r]-[0,l-1]后 ...

  4. 【BZOJ-1833】count数字计数 数位DP

    1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 2494  Solved: 1101[Submit][ ...

  5. 数位类统计问题--数位DP

    有一类与数位有关的区间统计问题.这类问题往往具有比较浓厚的数学味道,无法暴力求解,需要在数位上进行递推等操作.这类问题往往需要一些预处理,这就用到了数位DP. 本文地址:http://www.cnbl ...

  6. 数位dp——统计'1'的个数

    今天去牛客网看了看 包含一 这道题,一开始没看清,以为它要统计 1~n 所有数中数字 '1' 出现的总次数,也就是说,若 n == 11,则 ans = 4:而按照题目的原意 ans 应该为 3.看错 ...

  7. BZOJ_1833_[ZJOI2010]_数字计数_(数位dp)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1833 统计\(a~b\)中数字\(0,1,2,...,9\)分别出现了多少次. 分析 数位dp ...

  8. BZOJ 1833 数字计数 数位DP

    题目链接 做的第一道数位DP题,听说是最基础的模板题,但还是花了好长时间才写出来..... 想深入了解下数位DP的请点这里 先设dp数组dp[i][j][k]表示数位是i,以j开头的数k出现的次数 有 ...

  9. 51Nod 1009 数字1的个数 | 数位DP

    题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9 ...

随机推荐

  1. Linux新装系统简单指南

    也许更好的阅读体验 换源 1. 备份原来的源 sudo cp /etc/apt/sources.list /etc/apt/sources_init.list 2.更换源 先用\(gedit\)打开文 ...

  2. MOOC 数据库笔记(四):关系代数

    关系代数 关系代数概述 特点 基于集合,提供了一系列的关系代数操作:并.差.笛卡尔积(广义积).选择.投影和更名等基本操作 以及交.连接和关系除等扩展操作,是一种集合思维的操作语言. 关系代数操作以一 ...

  3. 一个牛逼的 Python 调试工具PySnooper

    原文转自:https://mp.weixin.qq.com/s/OtLr-cNethboMgmCcUx2pA PySnooper 使用起来十分简单,开发者可以在任何庞大的代码库中使用它,而无需进行任何 ...

  4. MySQL语法顺序及执行顺序

    一.书写顺序 select[distinct] from join on where group by having union order by limit 二.执行顺序 from on join ...

  5. Matlab状态模式

    状态模式就是将状态的条件判断语句转化成其函数重写形式,利用了面向对象语言的多态性,本文根据https://blog.csdn.net/lm324114/article/details/78819602 ...

  6. restfulframework引用多对多外键

    记录一下工作中遇到的问题 最近在写restfulframework,感觉还是很便利的 首先贴一下文档地址 https://www.django-rest-framework.org/api-guide ...

  7. linux安全加固项目

    分享一个Linux加固脚本项目,可快速对服务器进行安全加固,顺便做下备忘,安全人员必须熟悉运维相关的知识! 支持的操作系统平台: Amazon 2013.03 Amazon 2013.09 Amazo ...

  8. MySQL NULL--三值逻辑(Three Value Logic)

    三值逻辑(Three Value Logic) 在关系型数据库中,由于NULL值的存在,导致逻辑表达式存在三种值:TRUE/FALSE/UNKNOW. SELECT '=NULL AS C1, ' A ...

  9. Python,while循环小例子--猜拳游戏(三局二胜)

    Python,while循环小例子--猜拳游戏(三局二胜) import random all_choice = ['石头', '剪刀', '布'] prompt = '''(0)石头 (1)剪刀 ( ...

  10. ES6--不定参数

    <一>,在讨论ES6的不定参数之前,我们先一起回顾一下ECMAScript5的无名参数. 早先,javascript提供arguments对象检查函数的所有参数,从而不必定义每一个要用的参 ...