数位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]数字计数的更多相关文章

  1. 洛谷P2602 [ZJOI2010]数字计数 题解 数位DP

    题目链接:https://www.luogu.com.cn/problem/P2602 题目大意: 计算区间 \([L,R]\) 范围内 \(0 \sim 9\) 各出现了多少次? 解题思路: 使用 ...

  2. 数位DP 详解

    序 天堂在左,战士向右 引言 数位DP在竞赛中的出现几率极低,但是如果不会数位DP,一旦考到就只能暴力骗分. 以下是数位DP详解,涉及到的例题有: [HDU2089]不要62 [HDU3652]B-n ...

  3. P2602 [ZJOI2010]数字计数&P1239 计数器&P4999 烦人的数学作业

    P2602 [ZJOI2010]数字计数 题解 DFS 恶心的数位DP 对于这道题,我们可以一个数字一个数字的求 也就是分别统计区间 [ L , R ] 内部数字 i 出现的次数 (0<=i&l ...

  4. P2602 [ZJOI2010]数字计数(递推)

    P2602 [ZJOI2010]数字计数 思路: 首先考虑含有前导0的情况,可以发现在相同的\(i\)位数中,每个数的出现次数都是相等的.所以我们可以设\(f(i)\)为\(i\)位数每个数的出现次数 ...

  5. Luogu P2602 [ZJOI2010]数字计数 数位DP

    很久以前就...但是一直咕咕咕 思路:数位$DP$ 提交:1次 题解:见代码 #include<cstdio> #include<iostream> #include<c ...

  6. 洛谷P2602 [ZJOI2010]数字计数(数位dp)

    数字计数 题目传送门 解题思路 用\(dp[i][j][k]\)来表示长度为\(i\)且以\(j\)为开头的数里\(k\)出现的次数. 则转移方程式为:\(dp[i][j][k] += \sum_{t ...

  7. 动态规划晋级——HDU 3555 Bomb【数位DP详解】

    转载请注明出处:http://blog.csdn.net/a1dark 分析:初学数位DP完全搞不懂.很多时候都是自己花大量时间去找规律.记得上次网络赛有道数位DP.硬是找规律给A了.那时候完全不知数 ...

  8. 数位DP详解

    算法使用范围 在一个区间里面求有多少个满足题目所给的约束条件的数,约束条件必须与数自身的属性有关 下面用kuangbin数位dp的题来介绍 例题  不要62 题意:在一个区间里面求出有多少个不含4和6 ...

  9. P2602 [ZJOI2010]数字计数

    https://www.luogu.org/problemnew/show/P2602 数位dp #include <bits/stdc++.h> using namespace std; ...

随机推荐

  1. T2695 桶哥的问题——送桶 题解

    校内测试 ------T2 看完这个题,就觉得和贪心那一块的任务调度很像,于是思路就是贪心啦! 蒟蒻的我,也就只能想到用贪心了,但是不知道怎么用qwq 这是我考试当时的思路,数据水骗了80分qwq: ...

  2. Django从Models 10分钟定制一个Admin后台

    目录 Django从Models 10分钟建立一套RestfulApi Django从Models 10分钟定制一个Admin后台 简介 Django自带一个Admin后台, 支持用户创建,权限配置和 ...

  3. AcWing:237. 程序自动分析(离散化 + 并查集)

    在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,…x1,x2,x3,…代表程序中出现的变量,给定n个形如xi=xjxi=x ...

  4. Go 通道(channel)与协程间通信

    协程间通信 协程中可以使用共享变量来通信,但是很不提倡这样做,因为这种方式给所有的共享内存的多线程都带来了困难. 在 Go 中有一种特殊的类型,通道(channel),就像一个可以用于发送类型化数据的 ...

  5. redis常见7种使用场景

    一,简单字符串缓存实例 $redis->connect('127.0.0.1', 6379); $strCacheKey = 'Test_bihu'; //SET 应用 $arrCacheDat ...

  6. Linux中soft nproc 、soft nofile和hard nproc以及hard nofile配置

    Linux中soft nproc .soft nofile和hard nproc以及hard nofile配置 "soft" 和 "hard" 的区别 soft ...

  7. 对每个CheckBox的循环

    $("input[name='ck2']").each(function(){ if(this.checked == false){ $(this).parent().parent ...

  8. RabbitMQ学习之:(八)Topic Exchange (转贴+我的评论)

    From: http://lostechies.com/derekgreer/2012/05/18/rabbitmq-for-windows-topic-exchanges/ RabbitMQ for ...

  9. java的JDBC驱动使用链接数据库

    1.    import java.sql.*; 2 .    导入所需要的数据库的jar包,如oracle/informix的 3. String sql = "select * from ...

  10. linux备忘和卸载

    linux上网 -------------------------------------------------linux卸载------------------------------------ ...