题目链接: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\) 表示是否处于限制状态。

实现代码如下:

// P2602 [ZJOI2010]数字计数
#include <bits/stdc++.h>
using namespace std;
long long cnt[10], pow10[22], num;
int a[22];
struct Node {
long long arr[10];
Node() { memset(arr, 0, sizeof(arr)); }
void merge(Node v) {
for (int i = 0; i < 10; i ++)
arr[i] += v.arr[i];
}
} f[22][2];
bool vis[22][2];
void init() {
pow10[0] = 1;
for (int i = 1; i <= 18; i ++) pow10[i] = pow10[i-1] * 10;
}
Node dfs(int pos, int all0, bool limit) {
if (pos < 0) return Node();
if (!limit && vis[pos][all0]) return f[pos][all0];
int up = limit ? a[pos] : 9;
Node tmp = Node();
for (int i = 0; i <= up; i ++) {
if (i == 0 && all0 && pos>0) ;
else {
if (limit && i==up) tmp.arr[i] += num % pow10[pos] + 1;
else tmp.arr[i] += pow10[pos];
}
tmp.merge(dfs(pos-1, all0&&i==0, limit&&i==up));
}
if (!limit) {
vis[pos][all0] = true;
f[pos][all0] = tmp;
}
return tmp;
}
Node get_num(bool minus1) {
long long x;
cin >> x;
if (minus1) x --;
num = x;
int pos = 0;
while (x) {
a[pos++] = x % 10;
x /= 10;
}
if (num == 0) a[pos++] = 0;
return dfs(pos-1, true, true);
}
int main() {
init();
Node res_l = get_num(true);
Node res_r = get_num(false);
for (int i = 0; i < 10; i ++) {
if (i) putchar(' ');
cout << res_r.arr[i] - res_l.arr[i];
}
cout << endl;
return 0;
}

洛谷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. Android 使用SystemBarTint设置状态栏颜色

    做项目时,发现APP的状态栏是系统默认的颜色,突然想到,为啥别的APP是自己设置的颜色(和APP本身很相搭),于是也想给自己的APP设置系统状态栏的颜色,更加美美哒... 搜了下,发现原来设置状态栏居 ...

  2. SuperSocket 中的日志系统

    当 SuperSocket boostrap 启动时,日志系统将会自动启动. 所以你无须创建自己的日志工具,最好直接使用SuperSocket内置的日志功能. SuperSocket 默认使用log4 ...

  3. 微信小程序弹框wx.showModal如何修改样式

    由于官方API提供的显示模态弹窗,只能简单地显示文字内容,不能对对话框内容进行自定义,欠缺灵活性,所以自己从模态弹窗的原理角度来实现了自定义的模态对话框. wx.showModal修改样式后的效果,如 ...

  4. 不需内测账号,带你体验微信小程序完整开发过程

    不需内测账号,带你体验微信小程序完整开发过程 2016年09月24日 - 作者: SwiftCafe 微信小程序还没正式发布就已经迅速成为大家讨论的焦点,那么大家可能觉得只有收到内测邀请才能体验小程序 ...

  5. TabHost选项卡的实现(一):使用TabActivity实现

    一. TabHost的基本开发流程 TabHost是一种非常实用的组件,可以很方便的在窗口上防止多个标签页,每个标签页相当于获得了一个外部容器相同大小的组件摆放区域. 我们熟悉的手机电话系统" ...

  6. 2015年NOIP普及组复赛题解

    题目涉及算法: 金币:入门题: 扫雷游戏:入门题: 求和:简单数学推导: 推销员:贪心. 金币 题目链接:https://www.luogu.org/problem/P2669 入门题,直接开一个循环 ...

  7. 在vue项目中如何添加eslint

    随着vue的越做越好,更多的开发者选择使用vue,本篇记录如何在vue项目中添加eslint. 首先第一种就是在vue项目创建初始时就选择了创建,随着初始化一起代入到了项目当中,那么要是一开始觉得es ...

  8. 改善Azure App Service托管应用程序性能的几个技巧

    本文介绍了几个技巧,这些技巧可以改善Azure App Service托管应用程序的性能.其中一些技巧是你现在就可以进行的配置变更, 而其他技巧则可能需要对应用程序进行一些重新设计和重构. 开发者都希 ...

  9. C# 多线程的等待所有线程结束

      //前台线程和后台线程唯一区别就是:应用程序必须运行完所有的前台线程才可以退出://而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,//所有的后台线程在应用程序退出时都会自动结束 ...

  10. Recall(召回率);Precision(准确率);F1-Meature(综合评价指标);true positives;false positives;false negatives..

    转自:http://blog.csdn.net/t710smgtwoshima/article/details/8215037   Recall(召回率);Precision(准确率);F1-Meat ...