☆ [HDU2089] 不要62「数位DP」
类型:数位DP
传送门:>Here<
题意:问区间$[n,m]$的数字中,不含4以及62的数字总数
解题思路
数位DP入门题
先考虑一般的暴力做法,整个区间扫一遍,判断每个数是否合法并累计答案。而数位DP则认为可以换一种方法来枚举,找到对于一个数的上限,然后在这个限度内枚举每一个数位来统计答案
为了方便数位DP,题意可以转化求区间$[0, k]$的符合要求的数字总数,因此答案就是$ans(M)-ans(N-1)$
首先我们可以预处理出dp数组:$dp[i][j]$表示以$j$开头的$i$位数的符合要求的数字总数;例如,$dp[2][3]$表示以3开头的2位数中符合要求的,也就是区间$[30, 39]$中符合要求的。$$dp[i][j] = \sum\limits_{0 \leq k \leq 9 \\ \ k \neq 4}dp[i-1][k]$$这个方程很好理解,相当于枚举一个数位塞到前面,同时需要保证不能把6塞当2前面,并且特判一下4就好了
至于统计答案,我们从上限的最高位开始往下扫描。这里有个很巧妙的思想——每次处理不超过当前这一位的部分。形象地说,对于数字$21358$,最高位扫描$0~1$,也就是把答案累积上$dp[5][0~1]$。这一步相当于处理了区间$[0, 19999]$中的所有;此时默认最高位是2,扫描到下一位,累积$dp[4][0~0]$,也就相当于处理了区间$[20000,20999]$;依次类推,然后将会处理$[21000,21299]$,$[21300,21349]$,$[21350,21357]$。因此我们可以在$O(lg N * 10)$的复杂度内处理区间$[0, N-1]$。(注意不包括N)$$ans = \sum\limits_{i=num}^{1}\sum\limits_{j=0}^{digit[i]-1}dp[i][j]$$
然后在来看判断62和4的问题:每当我们进入到下一位,我们就将默认上一位确定。此时若确定的那一位为4,那么之后的都不用考虑了(一定不合法)。同理,如果当前确定的为2且上一位确定的为6,那么也可以跳出。事实上,这个跳出不是优化,而是必须那么做——如果不跳出,就会错误地累积很多答案。同时,不仅进入下一位的时候要判断,扫描的时候也要判断。道理一样
拓展:如果题目要求的不是【不要62】而是【要62】呢?就好像[HDU3555] Bomb所要求的一样,只需要求出所有的【不要62】数字,用N减一下就好了
Code
特别需要注意的是$digit[num+1]==0$这一步的处理,如果不加这一步,那么如果在处理前一个数字时残留下了$digit[num+1]==6$,那么你的程序将不能在最高位填充2了!
另外还有dp数组的初始化问题:一种是$dp[0][0]=1$,或者对于所有$i \neq 4$,$dp[1][i]=1$。其实这两者是等效的,因为在统计$dp[1][i]$时,只会累积到$dp[0][0]$为1
/*By DennyQi 2018.8.13*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXM = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x << ) + (x << ) + c - '', c = getchar(); return x * w;
}
int N,M,num,X,Y;
int dp[][],digit[];
inline void Init(){
dp[][] = ;
for(int i = ; i <= ; ++i){
for(int j = ; j <= ; ++j){
if(j == ) continue;
for(int k = ; k <= ; ++k){
if(k == && j == ) continue;
dp[i][j] += dp[i-][k];
}
}
}
}
inline int cul(int x){
num = ;
int y = x, res = ;
while(y > ){
digit[++num] = y % ;
y /= ;
}
digit[num+] = -;
for(int i = num; i >= ; --i){
for(int j = ; j < digit[i]; ++j){
if(digit[i+] == && j == ) continue;
res += dp[i][j];
}
if(digit[i] == || (digit[i+]==&&digit[i]==)) break;
}
return res;
}
int main(){
Init();
for(;;){
N = r, M = r;
if(!N && !M) break;
printf("%d\n",cul(M+)-cul(N));
}
return ;
}
☆ [HDU2089] 不要62「数位DP」的更多相关文章
- HDU2089 ------不要62(数位dp)
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- HDU2089 不要62 题解 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题目大意:求区间 \([l,r]\) 范围内不包含数字"4"且不包含连续的数 ...
- hdu2089不要62(数位dp)
#include <stdio.h> #include <string.h> ][]; ]; /* dp[i][0] 不含62,4 dp[i][1] 2开头 dp[i][2] ...
- HDU 2089 不要62(数位dp入门)
题意:统计区间 [a,b] 中不含 4 和 62 的数字有多少个. 题解:这是数位DP的入门题了,首先要理解数DP的原理,DP[i][j]:代表第i位的第j值,举个栗子:如4715 数位数是从右向 ...
- hdu2089 不要62--经典数位DP
一道十分经典的数位DP的题目. dp[i][j]表示最高位是数字i,连同最高位在内共有j位.注意边界的初始化. 接下来就是区间划分,特殊情况处理.....对了,如果不知道自己的方法是否正确,可以写一个 ...
- HDU 2089 不要62 【数位dp】
<题目链接> 不要62 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照 ...
- HDU 2089 不要62(数位dp模板题)
http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意:求区间内不包含4和连续62的数的个数. 思路: 简单的数位dp模板题.给大家推荐一个好的讲解博客.h ...
- HDU 2089 不要62【数位DP入门题】
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 【ACM】不要62 (数位DP)
题目:http://acm.acmcoder.com/showproblem.php?pid=2089 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新 ...
随机推荐
- 一款优秀的前端框架——AngularJS
前 言 AngularJS是一款为了克服HTML在构建应用上的不足而设计的优秀的前端JS框架.AngularJS有着诸多特性,最为核心的是:MVC.模块化.自动化双向数据绑定.语义化标签.依赖注 ...
- [书籍]用UWP复习《C#并发编程经典实例》
1. 简介 C#并发编程经典实例 是一本关于使用C#进行并发编程的入门参考书,使用"问题-解决方案-讨论"的模式讲解了以下这些概念: 面向异步编程的async和await 使用TP ...
- 《程序猿闭门造车》之NBPM工作流引擎 - 项目整体架构
前言: 又是一年一度的圣诞节,可这关我什么事呢 :( ,好不容易周末了,还是说说NBPM吧,前不久我发布了一篇关于工作流的文章:<程序猿闭门造车>之NBPM工作流引擎 - 开篇,很多爱好工 ...
- Atcoder E - Knapsack 2 (01背包进阶版 ex )
E - Knapsack 2 Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement The ...
- 20分钟 看图手写的table
<html><body><table width="100%" border="1" cellspacing="0&qu ...
- react render
实际上react render方法返回一个虚拟dom 并没有去执行渲染dom 渲染的过程是交给react 去完成的 这就说明了为什么要在所有数据请求完成后才去实现render 这样做也提高了性能.只调 ...
- oracle常用函数案例
--INSTR函数 SELECT INSTR(' HELLO WORLD','H') FROM DUAL; --LTRIM RTRIM函数 SELECT LTRIM('*HELLO=','*') FR ...
- springIOC源码分析(BeanFactroy)
启动spring容器加载bean的方式有两种:最基本的容器BeanFactory和高级容器ApplicationContext.这篇文章介绍使用BeanFactory加载bean时的整个过程,当然,A ...
- 使用Elasticsearch 出现的拒绝连接
pom 文件 spring: elasticsearch: jest: uris: http://192.168.124.142:9201 # data: # elasticsearch: # clu ...
- eclipse 部署项目