题解报告:hdu 2089 不要62

Problem Description

杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。

Input

输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。

Output

对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。

Sample Input

1 100
0 0

Sample Output

80
解题思路:模拟计数走一遍流程就清楚了,详解看代码。
AC代码一:
 #include<bits/stdc++.h>
using namespace std;
int n,m,dp[][],d[];
void init(){
memset(dp,,sizeof(dp));
dp[][]=;///特殊定义0位数首位是0的方案数为1
for(int i=;i<;++i){///表示i位数,最高位从1开始
for(int j=;j<;++j){///表示i位数的首位数字是j--->(0~9)
if(j==)continue;///如果当前首位为4,dp[i][j]=0
///累加i-1位数的首位是k的方案数,因为最高位已经确定,所以只需累加比其小的方案数即可
for(int k=;k<;++k){
if(j==&&k==)continue;///当前首位j与其右边这一位上的数字k不能组成62
dp[i][j]+=dp[i-][k];///状态转移方程
}
}
}
}
int solve(int x){///累加小于x的所有数的方案数,直到遇到4或者是62就退出累加
memset(d,,sizeof(d));///d数组记录x每一位上的数字
int len=,ans=;
while(x){///得到x的每一位数字
d[++len]=x%;
x/=;
}
///d[len+1]=0;///前面已经置0,避免产生上一次的结果6对这个统计的影响
for(int i=len;i>=;--i){///从高位向低位(从大到小)枚举位数i
for(int j=;j<d[i];++j){///巧妙处理:每当进入到下一位,就默认上一位确定
if(d[i+]==&&j==)continue;///跳过62,累加所有方案数
ans+=dp[i][j];///dp[i][4]都为0,所以这里无需判断j==4
}
///如果该位上是4或者(上一位是6并且当前位上是2)则直接退出后面的方案数的累加,因为后面的都不合法了
if(d[i]==||(d[i+]==&&d[i]==))break;
}
return ans;
}
int main(){
init();///预处理当前第i位首位是j符合条件的方案数
///for(int i=0;i<10;++i)cout<<dp[i][4]<<endl;
while(~scanf("%d%d",&n,&m)&&(n|m)){
printf("%d\n",solve(m+)-solve(n));
///差分思想,需要将[0,m+1)即[0,m]中的所有方案数减去[0,n)中的方案数才能得到[n,m]中满足条件的所有情况数
}
return ;
}

AC代码二:记忆化搜索。

 #include<bits/stdc++.h>
using namespace std;
int n,m,dp[][],d[];
///dp[pos][status]来保存在第pos位,status表示上一位是否为6这个状态
int dfs(int pos,bool if6,bool limit){///limit用来判断前一位是否为数位上界,是则本位不能取到大于a[pos]的数
if(!pos)return ;///特殊情况下为1,即dp[0][0]=1;
if(!limit&&dp[pos][if6]!=-)return dp[pos][if6];///若前一位不是上限,并且dp[pos][if6]已确定,直接return统计,这里体现了记忆化搜索
int up=limit?d[pos]:,ans=;///limit判断pos前的几位数字是否与n一样
for(int i=;i<=up;++i){
if(i==||(if6&&i==))continue;///这里is_6的值是0/1,用来区分前一位是否为6
///cout<<"当前第"<<pos<<"位,上限为"<<limit<<",前一个数是否为6:"<<if6<<",当前位为"<<i<<endl;
ans+=dfs(pos-1,i==6,limit&&i==up);
}
return limit?ans:(dp[pos][if6]=ans);///若前一位不是上限,即这一位可以达到最大,则更新dp值
}
int solve(int x){
memset(d,,sizeof(d));
int len=;
while(x){d[++len]=x%;x/=;}
return dfs(len,false,true);///刚开始前0位是相同的
}
int main(){
memset(dp,-,sizeof(dp));
while(~scanf("%d%d",&n,&m)&&(m|n)){
printf("%d\n",solve(m)-solve(n-));
}
return ;
}

数位dp知识点整理的更多相关文章

  1. 数位DP问题整理(一)

    第一题:Amount of degrees (ural 1057) 题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1057 题意:[x,y ...

  2. 数位dp整理

    数位dp的思想就在于递归,记录当前的某一个唯一状态,依次递归下去,要注意唯一. 数位dp常设的状态有当前位置,上一数字,是否具有前导零,是否有限制. 1.CodeForces 55DBeautiful ...

  3. 数位dp整理 && 例题HDU - 2089 不要62 && 例题 HDU - 3555 Bomb

    数位dp: 数位dp是一种计数用的dp,一般就是要统计一个区间[li,ri]内满足一些条件数的个数.所谓数位dp,字面意思就是在数位上进行dp.数位的含义:一个数有个位.十位.百位.千位......数 ...

  4. ACM个人零散知识点整理

    ACM个人零散知识点整理 杂项: 1.输入输出外挂 //读入优化 int 整数 inline int read(){ int x=0,f=1; char ch=getchar(); while(ch& ...

  5. 数位DP+其他

    参考资料: [1]:数位dp总结 之 从入门到模板 [2]:浅谈数位DP 题目一览表 来源 考察知识点 A 4352 "XHXJ's LIS" hdu 数位DP+状压DP+LIS ...

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

    正解:数位dp 解题报告: 传送门! 打算在寒假把学长发过题解的题目都做辣然后把不会的知识点都落实辣! ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄ 然后这道题,开始想到的时候其实想到的是大模拟,就有点像之前考试贪 ...

  7. Kuangbin 带你飞 数位DP题解

    以前一直不知道该咋搞这个比较好. 感觉推起来那个数字好麻烦.后来有一种比较好的写法就是直接的DFS写法.相应的ismax表示当前位是否有限制. 数位DP也是有一种类似模版的东西,不过需要好好理解.与其 ...

  8. HYSBZ 1026: windy数(数位DP)

    类型:数位DP题意:不含前导零且相邻两个数字之差至少为2的正整数被称为windy数.问[A,B]之间windy数的个数.(1 <= A <= B <= 2000000000 ) 思路 ...

  9. NOIP考前知识点整理

    前言:距离NOIP还有不到一百天(虽然NOIP没了),为了整理一下所学的内容,才有了这篇博文.本文内容无特殊说明全部来自于博主的博客,代码也都是新敲的,努力在个人的码风基础上做到尽量简洁,求资瓷. 一 ...

随机推荐

  1. NameNode备份策略以及恢复方法

    一.dits和fsimage      首先要提到两个文件edits和fsimage,下面来说说他们是做什么的. 集群中的名称节点(NameNode)会把文件系统的变化以追加保存到日志文件edits中 ...

  2. 20170225-ALV tree 显示

    1.写程序, 2.话屏幕9000,CALL SCREEN 9000.(双击屏幕进去画个容器就ok,+OK_CODE,+去掉注释) 3.处理好ALV 的PBO 初始化,处理用户事件PAO,user co ...

  3. React在Render中使用bind可能导致的问题

    因为bind在render的时候会重现生成,这样会导致props每次都不同, puremixin的插件也会失效. 所以需要将bind的结果缓存下来,或者直接在constructor里做这个事情 con ...

  4. vue 中的组件通信

    vue中组件通信,一般分为三种情况,父与子,子与父,子子之间. 一.父与子通信 父组件将值传给子组件,一般通过props,设置默认的类型.调用的时候通过 xx=" ", 或者:XX ...

  5. js与原生的交互

    一.与安卓的交互 Android与js通过WebView互相调用方法,实际上是: Android去调用JS的代码 JS去调用Android的代码 二者沟通的桥梁是WebView 对于android调用 ...

  6. HDU2732 Leapin' Lizards —— 最大流、拆点

    题目链接:https://vjudge.net/problem/HDU-2732 Leapin' Lizards Time Limit: 2000/1000 MS (Java/Others)    M ...

  7. codeforces 459 A. Pashmak and Garden 解题报告

    题目链接:http://codeforces.com/problemset/problem/459/A 题目意思:给出两个点的坐标你,问能否判断是一个正方形,能则输出剩下两点的坐标,不能就输出 -1. ...

  8. cassandra cpp driver中bind list——用cass_statement_bind_collection函数

    CassError insert_into_collections(CassSession* session, const char* key, const char* items[]) { Cass ...

  9. Objective-C Runtime(二)消息传递机制

    在对象上调用方法是包括Objective-C的众多语言都具备的功能.但在Objective-C中,这个术语叫『传递消息』(pass a message).『消息』有「名称」(name)或「选择子」(s ...

  10. Python项目使用memcached缓存

    前言许多Web应用都将数据保存到MySQL这样的关系型数据库管理系统中,应用服务器从中读取数据并在浏览器中显示. 但随着数据量的增大.访问的集中,就会出现数据库的负担加重.数据库响应恶化. 网站显示延 ...