题解报告: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代码一:
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,m,dp[][],d[];
  4. void init(){
  5. memset(dp,,sizeof(dp));
  6. dp[][]=;///特殊定义0位数首位是0的方案数为1
  7. for(int i=;i<;++i){///表示i位数,最高位从1开始
  8. for(int j=;j<;++j){///表示i位数的首位数字是j--->(0~9)
  9. if(j==)continue;///如果当前首位为4,dp[i][j]=0
  10. ///累加i-1位数的首位是k的方案数,因为最高位已经确定,所以只需累加比其小的方案数即可
  11. for(int k=;k<;++k){
  12. if(j==&&k==)continue;///当前首位j与其右边这一位上的数字k不能组成62
  13. dp[i][j]+=dp[i-][k];///状态转移方程
  14. }
  15. }
  16. }
  17. }
  18. int solve(int x){///累加小于x的所有数的方案数,直到遇到4或者是62就退出累加
  19. memset(d,,sizeof(d));///d数组记录x每一位上的数字
  20. int len=,ans=;
  21. while(x){///得到x的每一位数字
  22. d[++len]=x%;
  23. x/=;
  24. }
  25. ///d[len+1]=0;///前面已经置0,避免产生上一次的结果6对这个统计的影响
  26. for(int i=len;i>=;--i){///从高位向低位(从大到小)枚举位数i
  27. for(int j=;j<d[i];++j){///巧妙处理:每当进入到下一位,就默认上一位确定
  28. if(d[i+]==&&j==)continue;///跳过62,累加所有方案数
  29. ans+=dp[i][j];///dp[i][4]都为0,所以这里无需判断j==4
  30. }
  31. ///如果该位上是4或者(上一位是6并且当前位上是2)则直接退出后面的方案数的累加,因为后面的都不合法了
  32. if(d[i]==||(d[i+]==&&d[i]==))break;
  33. }
  34. return ans;
  35. }
  36. int main(){
  37. init();///预处理当前第i位首位是j符合条件的方案数
  38. ///for(int i=0;i<10;++i)cout<<dp[i][4]<<endl;
  39. while(~scanf("%d%d",&n,&m)&&(n|m)){
  40. printf("%d\n",solve(m+)-solve(n));
  41. ///差分思想,需要将[0,m+1)即[0,m]中的所有方案数减去[0,n)中的方案数才能得到[n,m]中满足条件的所有情况数
  42. }
  43. return ;
  44. }

AC代码二:记忆化搜索。

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

数位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. ios+Appium+Java

    To run iOS tests, you can follow these steps : (Note : I am using Java language here in Eclipse IDE ...

  2. OpenGL之路(五)制作旋转飞机模型

    #include <gl/glut.h> #include <gl/GLU.h> #include <gl/GL.h> #pragma comment(lib, & ...

  3. C++的string连接(a = a + b 与 a += b)

    大一学习C语言的时候,书上就写着a = a + b与 a += b等价,但是提倡用后者. 在CSDN上也看到一个关于a+=b和a=a+b的区别的帖子,大概内容如下:------------------ ...

  4. Phoenix(SQL On HBase)安装和使用报告

    一.为什么使用Phoenix二.安装Phoenix2.1 兼容问题?2.2 编译CDH版本的Phoenix2.3 安装Phoenix到CDH环境中三.Phoenix的使用3.1 phoenix的4种调 ...

  5. [转]GPS经纬度的表示方法及换算

    想要认识GPS中的经纬度,就必须先了解GPS,知道经纬度的来源: 1. GPS系统组成 GPS是 Gloabal Positioning System 的简称,意为全球定位系统,主要由地面的控制站.天 ...

  6. Jmeter代理服务器录制请求

    1.文档前提说明 1)本文使用jmeter的版本为 apache-jmeter-2.13 及以上版本 2)java版本要求在 1.8.0 以上 注:jmeter版本一般和java相应的版本一起使用,如 ...

  7. HDU 5627Clarke and MST

    Clarke and MST Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  8. HDU1560 DNA sequence —— IDA*算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1560 DNA sequence Time Limit: 15000/5000 MS (Java/Oth ...

  9. YTU 2443: C++习题 复数类--重载运算符3+

    2443: C++习题 复数类--重载运算符3+ 时间限制: 1 Sec  内存限制: 128 MB 提交: 1368  解决: 733 题目描述 请编写程序,处理一个复数与一个double数相加的运 ...

  10. driver, module以及怎么看他们

    1. driver和module的区别 https://unix.stackexchange.com/questions/47208/what-is-the-difference-between-ke ...