数位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; ...
随机推荐
- GC 老年代 新生代
参考资料: http://blog.csdn.net/flamezyg/article/details/44673951 http://www.blogjava.net/ldwblog/archive ...
- 记一次phoenix在不加索引的情况调优,由6s以上时间变成不到1s
背景: 网约车预约单查询: 这里面恶心的地方是: 1个时间窗口要查询6种时间:推送订单时间(来自mongodb).有效抢单时间(来自mongodb).抢单成功时间(实时kafka).取消订单时间(实时 ...
- IntelliJ IDEA利用Maven下载所需的JAR包到项目中
直接复制JetBrains/../conf/settings.xml后修改镜像出现问题,然后用了这里的settings.xml配置文件.
- 九款Web服务器性能压力测试工具
一.http_load 程序非常小,解压后也不到100Khttp_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会 ...
- 【转】Qt编写串口通信程序全程图文讲解
本文章原创于www.yafeilinux.com 转载请注明出处. (说明:我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自 ...
- Rocketmq异步发送消息
package com.bfxy.rocketmq.quickstart; import java.util.List; import org.apache.rocketmq.client.excep ...
- Kotlin函数中默认参数
Java不支持默认参数.但kotlin函数却可以 package loaderman.demo class Customer(var name:String ="name"){// ...
- UML绘图工具
画UML图与写文章差不多,都是把自己的思想描述给别人看,关键在于思路和条理,图好看与否就是看你的字是否规范,至于工具,就像你用什么笔,不算非常重要. 目前市场上常见的建模工具有StarUML,IBM ...
- css清除浮动的几种方式,哪种最合适?
细心的人可能发现了,写的导航条中存在一个问题,那就是使用了float之后,父级盒子的高度变为0了. 我们来写一个例子来看一下,创建一个父级div,并设置border属性,然后下边创建两个子元素span ...
- Qt编写自定义控件19-图片背景时钟
前言 图片背景时钟控件,是全套控件(目前共145个)中唯一的几个贴图的控件,这个背景要是不贴图,会画到猝死,必须用美工做好的图贴图作为背景,此控件以前学C#的时候写过,后面在写Qt控件的过程中把他移植 ...