【题解】P2602 数字计数 - 数位dp
P2602 [ZJOI2010]数字计数
题目描述
给定两个正整数 \(a\) 和 \(b\) ,求在 \([a,b]\) 中的所有整数中,每个数码(digit)各出现了多少次。
输入格式
输入文件中仅包含一行两个整数\(a,b\),含义如上所述。
输出格式
输出文件中包含一行 \(10\) 个整数,分别表示 \(0-9\) 在 \([a,b]\) 中出现了多少次。
说明/提示
\(30\%\)的数据中,\(a<=b<=10^6\);
\(100\%\)的数据中,\(a<=b<=10^{12}\)。
Solution
此题解仅讲想法,不讲有关数位 \(dp\)的基础知识或写法,如果还没有学过数位 \(dp\) 的可以先看别的题目
看到题解里用 \(dfs\) 做的都是设的两维或以上的状态,实际上这道题只需要一维状态就够了
设目前已经填到了第 \(pos\) 位,则不管 \(num\ -\!-\ \ pos + 1\) 位上填的是什么,之后的 \(1\ -\!-\ pos\)位上的贡献是不变的(除非是已经到了 \(limit\) 的限制了,这个之后再讨论)
那么状态很明显为 \(f[pos]\)
\(eg:\)现在要填五位的数,目前状态为 \(12XXX\), \(limit\) 为 \(30000\),则后面的三位可以直接由 \(f[3]\) 转移过来,因为这属于子结构,不对前面造成影响
为什么可以这样转移?
前面所填的数(类似于 \(eg\) 中的 \(12XXX\) 的 \(12\))的贡献如何计算?
我们可以发现,对于 \(12XXX\) 中 第四位上的 \(2\) 的贡献,是 \(10^{pos - 1}\) 的。因为 \(12XXX\) 的后三位可以填 \(000\) - \(999\) 中的任意一种,则第四位的 \(2\) 就被计算了 \(10^3\) 次,即贡献就是 \(10^{pos - 1}\)。注意:这里所讨论的 \(2\) 的贡献值,仅考虑第四位上的 \(2\) ,对于后面位置上的为子结构,在之后会考虑到,而前面位置上的,在之前已经预先考虑过了,所以不会重复也不会漏情况。
现在再来讨论 \(limit\) 的限制情况。
假设将 \(eg\) 中的 \(limit\) 改为 \(12300\),则填后三位时就只能填 \(000\) - \(300\),总共是 \(12300 - 12000 + 1\) 种,于是只用在计算贡献时加这样一个判断就可以了。
Code
#include<bits/stdc++.h>
#define ll long long
#define F(i, x, y) for(int i = x; i <= y; ++ i)
using namespace std;
const int N = 15;
ll L, R;
int cnt[N];
ll f[N];
ll add(int pos)//计算lim限制时的贡献
{
ll ans = 0;
for(int i = pos - 1; i >= 1; -- i) ans = ans * 10 + cnt[i];
return ans + 1;
}
ll dp(int pos, int x, int lim, int last)
{/* pos为第几位 x为现在在算的数码
lim为是否为限制 last为上一次的值(处理前导零)*/
if(! pos) return 0;
if(! lim && f[pos] != -1 && last != 10) return f[pos];
ll ret = 0;
F(i, (last == 10 ? 1 : 0), (lim ? cnt[pos] : 9))
{
if(i == x && (i != cnt[pos] || ! lim)) ret += pow(10, pos - 1);
else if(i == x) ret += add(pos);//分情况计算贡献
ret += dp(pos - 1, x, lim && i == cnt[pos], i);
}
if(last == 10) ret += dp(pos - 1, x, 0, last);
if(! lim) f[pos] = ret;
return ret;
}
ll work(int x, ll r)
{
memset(f, -1, sizeof(f));
int num = 0;
for(r; r; r /= 10) cnt[++ num] = r % 10;
return dp(num, x, 1, 10);
}
int main()
{
cin >> L >> R;
F(i, 0, 9) printf("%lld ", work(i, R) - work(i, L - 1));
printf("\n");
return 0;
}
Thanks
如果有任何疑问欢迎提出或和我一起讨论(′▽`〃)
【题解】P2602 数字计数 - 数位dp的更多相关文章
- 洛谷 - P2602 - 数字计数 - 数位dp
https://www.luogu.org/problemnew/show/P2602 第二道数位dp,因为“数位dp都是模板题”(误),所以是从第一道的基础上面改的. 核心思想就是分类讨论,分不同情 ...
- [bzoj1833][ZJOI2010]count 数字计数——数位dp
题目: (传送门)[http://www.lydsy.com/JudgeOnline/problem.php?id=1833] 题解: 第一次接触数位dp,真的是恶心. 首先翻阅了很多很多一维dp,因 ...
- Luogu P2602 [ZJOI2010]数字计数 数位DP
很久以前就...但是一直咕咕咕 思路:数位$DP$ 提交:1次 题解:见代码 #include<cstdio> #include<iostream> #include<c ...
- 洛谷P2602 [ZJOI2010]数字计数(数位dp)
数字计数 题目传送门 解题思路 用\(dp[i][j][k]\)来表示长度为\(i\)且以\(j\)为开头的数里\(k\)出现的次数. 则转移方程式为:\(dp[i][j][k] += \sum_{t ...
- bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)
1833: [ZJOI2010]count 数字计数 题目:传送门 题解: 今天是躲不开各种恶心DP了??? %爆靖大佬啊!!! 据说是数位DP裸题...emmm学吧学吧 感觉记忆化搜索特别强: 定义 ...
- 【BZOJ-1833】count数字计数 数位DP
1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 2494 Solved: 1101[Submit][ ...
- BZOJ 1833 数字计数 数位DP
题目链接 做的第一道数位DP题,听说是最基础的模板题,但还是花了好长时间才写出来..... 想深入了解下数位DP的请点这里 先设dp数组dp[i][j][k]表示数位是i,以j开头的数k出现的次数 有 ...
- UVA.1640.The Counting Problem / BZOJ.1833.[ZJOI2010]数字计数(数位DP)
题目链接 \(Description\) 求\([l,r]\)中\(0,1,\cdots,9\)每个数字出现的次数(十进制表示). \(Solution\) 对每位分别DP.注意考虑前导0: 在最后统 ...
- 1833: [ZJOI2010]count 数字计数——数位dp
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1833 省选之前来切一道裸的数位dp.. 题意 统计[a,b]中0~9每个数字出现的次数(不算 ...
随机推荐
- stm32CubeMx+TrueSTUDIO+uc/os-III移植开发(一)
自从接触到stm32cubemx后,发现使用起来很方便,用来做项目开发的话,由于是图形化操作界面,工作效率比较快.如果要学习操作系统,以前的IDE如keil,IAR等IDE对操作系统的代码调试起来不够 ...
- OpenCV-Python 绘图功能 | 七
目标 学习使用OpenCV绘制不同的几何形状 您将学习以下功能:cv.line(),cv.circle(),cv.rectangle(),cv.ellipse(),cv.putText()等. 代码 ...
- iOS 继承
是否使用继承需要考虑三个点: 父类只是给子类提供服务,并不涉及子类的业务逻辑 层级关系明显,功能划分清晰,父类和子类各做各的. 父类的所有变化,都需要在子类中体现,也就是说此时耦合已经成为需求 万不得 ...
- MATLAB 图像打开保存
一.图片读取保存 (1)读取 clear all [filename,pathname]=uigetfile({'*.jpg';'*.bmp';'*.gif'},'选择图片'); if isequal ...
- 数据结构与算法复习-----leetcodeOJ题解
Isomorphic Strings Given two strings s and t, determine if they are isomorphic. Two strings are isom ...
- bs4使用
目录 安装使用 遍历文档树 查找文档树 安装使用 # 安装 pip3 install beautifulsoup4 from bs4 import BeautifulSoup soup=Beautif ...
- K - 回转寿司(值域段数(板题) + 动态开点)
回转寿司 Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店.在这里,一盘盘寿司通过传送带依次呈现在小Z眼前.不同的寿 司带给小Z的味觉感受是不一样的,我们定义小Z对每盘寿司都有一个 ...
- My背包九讲——01背包
文章目录 背包问题中的常用变量说明 题目 解题思路 我想要想理解最简单 01背包就是要`理解
- 《Three.js 入门指南》3.1.1 - 基本几何形状 -圆环结(TorusKnotGeometry)
3.1 基本几何形状 圆环结(TorusKnotGeometry) 构造函数 THREE.TorusKnotGeometry(radius, tube, radialSegments, tubular ...
- Qt实现学生学籍管理系统(文件存储)
记录 19:53 2019-07-30 在小学期学c++做完课设后萌生了把写完的课设放在博客上的想法,于是,我第一篇博客诞生了. 22:32:19 2019-07-30 下棋 16:04:56 201 ...