数位dp详解&&LG P2602 [ZJOI2010]数字计数
数位dp,适用于解决一类求x~y之间有多少个符合要求的数或者其他。
例题
题目描述
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
输入输出格式
输入的都是整数对A、B(0<A≤B<10^9),如果遇到都是0的整数对,则输入结束。
数据规模
20% 的数据,满足 1≤A≤B≤10^6;
100%的数据,满足 1≤A≤B≤2×10^9。
解法
用solve(x)
求0~x中符合要求的数有几个;那么答案显然就是solve(b)-solve(n-1)
那么如何solve呢?用记忆化搜索(不用搜索而用普通dp也行,但要麻烦一点)
我们考虑从高位往低位枚举:
如果前面的所有位都“取到顶了”,那么下一位只能取0这一位:比如4375前两位取了43,那么下一位只能取0这一位,也就是0~7
否则,下一位可以取0~9
我们使用flag来表示前几位有没有“取到顶”
f[l][lst]表示的是整个长度为l的数的前面一位是lst的数有多少个。比如f[3][5]表示的就是形如5 ___ ___ ___
的数有多少个(注意:不是形如5 ___ ___
!)
需要注意的是,只能在flag=0的情况下才能记忆化,因为flag=0时后面是可以取满的;flag=1时后面取不满,而且上限是不定的。
具体实现详见注释。
#include<bits/stdc++.h>
using namespace std;
if(!flag&&f[l][lst]!=-1) return f[l][lst];//记忆化
int u=flag?d[l]:9,anstmp=0;
for(int i=0;i<=u;i++)
if(i!=4&&!(lst==6&&i==2)) //这一位4或者前一位是6这一位是2(也就是组成62)是不行的。
anstmp+=dfs(l-1,i,flag&&i==u);
return flag?anstmp:f[l][lst]=anstmp;//只有flag=0时才能记忆化!
}
inline int solve(int k)
{
cnt=0;
while(k)
{
d[++cnt]=k%10;
k/=10;
}//先将当前的数一位一位拆开
return dfs(cnt,0,1);
}
int main()
{
memset(f,-1,sizeof(f));
while(scanf("%d %d",&n,&m)!=EOF)
{
if(n==m&&n==0) break;
printf("%d\n",solve(m)-solve(n-1));
}
return 0;
}
P2602 [ZJOI2010]数字计数
题目描述
给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码 (digit) 各出现了多少次。
输入格式
仅包含一行两个整数 a,b,含义如上所述。
输出格式
包含一行 10个整数,分别表示 0∼9在[a,b]中出现了多少次。
数据规模
30%的数据中,1≤a≤b≤10^6;
100%的数据中,1≤a≤b≤10^12。
实现
ans[0~9]表示题目的答案。
f[l][lst][11]:f[l][lst][09]表示09各有多少个,f[l][lst][10]表示有几个数
f[l][lst][10]很好算,f[l][lst][0~9]直接算不好算,我们采取在dfs前和dfs后的ans数组做差的方法求出。
dfs中的tstep是调试用的,不用管;dfs中的t是表示加或者减的,因为是0m的答案**减去**0n-1的答案,所以求0m时t=1,0n-1时t=-1
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,cnt=0,d[1005],f[1005][1005][11],k,b,ans[1005],bf[1005];
ll dfs(ll l,ll lst,bool flag,bool flagg,ll t,ll tstep)
{
if(l==0) return 1;
if(!flag&&!flagg&&f[l][lst][10]!=-1)
{
for(ll i=0;i<=9;i++) ans[i]+=f[l][lst][i]*t;
return f[l][lst][10];
}
ll u=(flag?d[l]:9),anstmp=0;
for(int i=0;i<=9;i++) bf[i]=ans[i];
for(ll i=0;i<=u;i++)
{
ll tttmp=dfs(l-1,i,flag&&i==u,flagg&&i==0,t,tstep+1);
if(i!=0||!flagg)
{
ans[i]+=tttmp*t;
anstmp+=tttmp;
}
}
if(!flag&&!flagg) {for(int i=0;i<=9;i++) {f[l][lst][i]=abs(ans[i]-bf[i]);}}
return (flag||flagg)?anstmp:f[l][lst][10]=anstmp;
}
inline ll solve(ll k,ll t)
{
cnt=0;
while(k)
{
d[++cnt]=k%10;
k/=10;
}
return dfs(cnt,0,1,1,t,0);
}
int main()
{
memset(f,-1,sizeof(f));
scanf("%lld %lld",&n,&m);
solve(m,1);
solve(n-1,-1);
for(ll i=0;i<=8;i++) printf("%lld ",ans[i]);
printf("%lld",ans[9]);
return 0;
}
数位dp详解&&LG P2602 [ZJOI2010]数字计数的更多相关文章
- 洛谷P2602 [ZJOI2010]数字计数 题解 数位DP
题目链接:https://www.luogu.com.cn/problem/P2602 题目大意: 计算区间 \([L,R]\) 范围内 \(0 \sim 9\) 各出现了多少次? 解题思路: 使用 ...
- 数位DP 详解
序 天堂在左,战士向右 引言 数位DP在竞赛中的出现几率极低,但是如果不会数位DP,一旦考到就只能暴力骗分. 以下是数位DP详解,涉及到的例题有: [HDU2089]不要62 [HDU3652]B-n ...
- P2602 [ZJOI2010]数字计数&P1239 计数器&P4999 烦人的数学作业
P2602 [ZJOI2010]数字计数 题解 DFS 恶心的数位DP 对于这道题,我们可以一个数字一个数字的求 也就是分别统计区间 [ L , R ] 内部数字 i 出现的次数 (0<=i&l ...
- P2602 [ZJOI2010]数字计数(递推)
P2602 [ZJOI2010]数字计数 思路: 首先考虑含有前导0的情况,可以发现在相同的\(i\)位数中,每个数的出现次数都是相等的.所以我们可以设\(f(i)\)为\(i\)位数每个数的出现次数 ...
- 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 ...
- 动态规划晋级——HDU 3555 Bomb【数位DP详解】
转载请注明出处:http://blog.csdn.net/a1dark 分析:初学数位DP完全搞不懂.很多时候都是自己花大量时间去找规律.记得上次网络赛有道数位DP.硬是找规律给A了.那时候完全不知数 ...
- 数位DP详解
算法使用范围 在一个区间里面求有多少个满足题目所给的约束条件的数,约束条件必须与数自身的属性有关 下面用kuangbin数位dp的题来介绍 例题 不要62 题意:在一个区间里面求出有多少个不含4和6 ...
- P2602 [ZJOI2010]数字计数
https://www.luogu.org/problemnew/show/P2602 数位dp #include <bits/stdc++.h> using namespace std; ...
随机推荐
- Codeforces 576D Flights for Regular Customers (图论、矩阵乘法、Bitset)
题目链接 http://codeforces.com/contest/576/problem/D 题解 把边按\(t_i\)从小到大排序后枚举\(i\), 求出按前\((i-1)\)条边走\(t_i\ ...
- 如何用20行Python代码打造一个微信群聊助手?
今天要教大家一个黑科技,20行代码实现自己定制的微信群聊助手,可以用来活跃群气氛,好多群主创建完群后,拉完一群人,之后就一片寂静,有个群聊助手,就可以帮忙活跃群里气氛,通过今天在自己的微信上有一大批好 ...
- UVA 247 Calling Circles —— (强连通分量模板题)
第一个强连通分量的题. 题意:有一堆人,a给b打电话表示a有一条向b的边,一个强连通分量代表一个电话圈,把每个电话圈里的人在一行内输出出来. 直接上模板即可,但是要注意把string用map映射一下的 ...
- apidoc 接口文档系统
代码未动,文档先行.apidoc可以方便地维护接口文档.模拟响应数据.前后端分离.导出PDF文档. 特性说明 可视化编辑:支持表单界面编辑接口,不必手动编辑swagger.json 接口模拟响应:支持 ...
- pytorch-VGG网络
VGG网络结构 第一层: 3x3x3x64, 步长为1, padding=1 第二层: 3x3x64x64, 步长为1, padding=1 第三层: 3x3x64x128, 步长为1, paddin ...
- Redis | Redis基础都不会,好意思出去面试?
Redis的数据结构 Redis支持多种不同的数据结构,包括5种基础数据结构和几种比较复杂的数据,这些数据结构可以满足不同的应用场景. 五种基础数据结构 String:字符串,是构建其他数据结构的基础 ...
- 【Taro全实践】6位验证码输入视觉分离(标准下划线分离)
一.实现的效果图 二.实现思路 中间想过很多实现方法,但是因为input为原生组件的原因,很难适配所有手机直接. 所有如何实现适配所有手机的验证码分离输入呢?(思路如下) 1.input组件为原生组件 ...
- C# 打包安装部署 属性中找不到 查找目标或打开文件位置
用第三方工具OrcaMis (一个可以修改msi文件的工具)来实现的 最后我又试了几次,以为是再程序打包的时候设置有问题,结果都没有找到原因,没有办法只有需求网络资源,网络上有朋友说VS创建的快捷方式 ...
- 一百零三:CMS系统之使用sweetalert提示框优化返回结果
在base模板中引用 在修改密码的js中使用 $(function () { $('#submit').click(function (evnet) { evnet.preventDefault(); ...
- Linux文档中翻页和搜索关键字
按键 进行工作空格键 向下翻一页[Page Down] 向下翻一页[Page Up] 向上翻一页[Ctrl + U] 向上翻一页[Ctrl + D] 向下翻一页/string 向下搜寻string这个 ...