☆ [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).杭州交通管理局经常会扩充一些的士车牌照,新 ...
随机推荐
- 解决win7 win10上网卡慢问题
在管理员身份运行CMD命令行,然后输入netsh interface tcp set global autotuninglevel=disable 即可.
- CF每日一练 Codeforces Round #520 (Div. 2)
比赛过程总结:过程中有事就玩手机了,后面打的状态不是很好,A题理解错题意,表明了内心不在状态,B题想法和思路都是完全正确的,但是并没有写出来,因为自己代码能力不强,思路不是特别清晰,把代码后面写乱了, ...
- 用C# BigInteger实现的BigDecimal类,终于可以直接做四则运算了。
https://code.google.com/p/dotnet-big-decimal/ 这是个BigDecimal类的开源项目,支持Operators +, - and *. 俺给改了改,加上了除 ...
- Python集合及其运算
目录 集合(set) 集合的创建 集合的操作 集合的运算 子集与父集 集合(set) 集合是由不同可hash的值组成的,里面所有的值都是唯一的,也是无序的 集合的创建 >>>set_ ...
- Elasticsearch之配置详解
Cluster 集群名称,默认为elasticsearch: cluster.name: elasticsearch 设置一个节点的并发数量,有两种情况,一种是在初始复苏过程中: cluster.ro ...
- 配置react-sass
在配置react-sass时遇到很多坑其中 一条如果你的.scss文件失效 请一定要在fileloader之前配置该sass-loader 配置文件如下 基于你不熟悉webpack 容易出这个错误
- [转帖]SAP S/4 HANA与SAP Business Suite/R3(ECC)的区别
SAP S/4 HANA与SAP Business Suite/R3(ECC)的区别 https://blog.csdn.net/zhongguomao/article/details/5351520 ...
- 判断浏览器是否支持H5
window.onload = function() { if (!window.applicationCache) { alert("请升级您的浏览器版本,你的浏览器不支持HTML5!&q ...
- Spring boot + mybatis + orcale实战(干货)
废话少说,直接上步骤: 第一步:安装好IDEA(此处省略) 第二步:在IDEA新建springboot工程 第三步:在springboot工程的pom.xml添加oracle和mybait依赖 < ...
- NOIP2016提高组复赛C 愤怒的小鸟
题目链接:http://uoj.ac/problem/265 题目大意: 太长了不想概括... 分析: 状压DP的模板题,把所有可能的抛物线用二进制表示,然后暴力枚举所有组合,详情见代码内注释 代码如 ...