链接:https://vjudge.net/problem/23625/origin

中文,题目不用说了。

其实这题的数据很小,所以直接暴力也可以过,但是还是要学会数位dp,因为并不是每一题的数据都会这么小,这里给出我暴力的代码和数位dp的代码(数位dp其实也是有一个大致的模板的)。

暴力:

#include<stdio.h>
#include<string.h>
int dp[];
int n,m,k,t;
int jug(int a)
{
while(a)
{
if(a%==)
return ;
if(a%==&&a/%==&&a>=)
return ;
a/=;
}
return ;
}
int main()
{
memset(dp,,sizeof(dp));
for(int i=;i<=;i++)
{
if(jug(i))
dp[i]=dp[i-]+;
else
dp[i]=dp[i-];
}
while(scanf("%d%d",&n,&m)!=EOF)
{
if(!n&&!m)
break;
if(m<n)
printf("%d\n",);
else
printf("%d\n",dp[m]-dp[n-]);
}
return ;
}

接下来我只是说一下我的看法,可能不是非常准确,能大致看懂就好。现在假设我们求0到625符合条件的数字有多少个,那么我们把625的每一位存进一个digit数组,先介绍一下我们递归时的顺序(值始终不能超过625),先把百位拿出来,因为百位为6,那么我们可以这样找

先找百位,百位的上界为6,所以百位是受到约束的,最大只能取6,所以百位可以取0,1,2,3,4,5,6。

接下来找十位,0_ _,1_ _,2_ _,3_ _,4_ _,5_ _,前面的这些它们的十位不受约束可以随便取(比如00_,01_,... 09_,  10_,11_...19_  ... 59_),从0到9都可以。

但是到了6(6_ _)就要控制后面的数字了,因为它的十位最大只能取2,所以我们只能取6 0 _,6 1_,6 2 _,同样,在我们递归到了十位时,如果百位是0到5,那么它们的个位也是不受约束的,所以也可以随便取,

但是如果百位是6,那么我们又要看情况了,如果是60_,或者是61_,那么它们的个位也是不受约束的,可以随便取,但是如果是62_,那么它的个位是受到约束的,最大只能到5。

应该差不多了,在程序里,我们从最高位一直递归到个位,同时把当前位不受约束的状态的值保存下来,pos表示现在到了

哪一位(百位?十位?个位?),flag表示到到当前状态为止是否符合条件(0或1),pre表示当前状态的前一位数字是多少(判断是不是有62),limit就是控制上界的关键,我们把它初始化为1,表示目前它的最高位收到限制,在之后的过程中

如果limit为0,那么接下来所有的递归过程里数字都是0到9,都可以取,都可以记忆保存,可能看文字不是特别明白,

还是看看代码吧:

#include<stdio.h>
#include<string.h>
int dp[][][];
int digit[];
int n,m,k,t;
void init()
{
memset(dp,-,sizeof(dp));
}
int dfs(int pos,int flag,int pre,int limit)//当前位,是否满足条件,前一位,控制上界
{
if(!pos)//到了个位,返回值
return flag;
if(!limit&&dp[pos][pre][flag]!=-)//直接输出之前记录的值,节省时间
return dp[pos][pre][flag];
int num=limit?digit[pos]:;//非常关键的东西,如果limit为1,那么这个位置受到约束,最大只能为digit[pos]
int s=; //否则它就不受约束,可以为任何值
for(int i=;i<=num;i++)
{
if(pre==&&i==||!flag||i==)
s+=dfs(pos-,,i,limit&&i==num);//这个limit&&i==num是为了确定下一位数是否受约束
else
s+=dfs(pos-,,i,limit&&i==num);
}
if(!limit&&dp[pos][pre][flag]==-)//记录
dp[pos][pre][flag]=s;
return s; }
int cal(int a)
{
int len=;
memset(digit,,sizeof(digit));
while(a)
{
digit[++len]=a%;
a/=;
}
return dfs(len,,,);
}
int main()
{
init();
while(scanf("%d%d",&n,&m)!=EOF)
{
if(!n&&!m)
break;
printf("%d\n",cal(m)-cal(n-));
}
return n;
}

hdu 2089 数位dp的更多相关文章

  1. hdu:2089 ( 数位dp入门+模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 数位dp的模板题,统计一个区间内不含62的数字个数和不含4的数字个数,直接拿数位dp的板子敲就行 ...

  2. HDU 2089 数位dp入门

    开始学习数位dp...一道昨天看过代码思想的题今天打了近两个小时..最后还是看了别人的代码找bug...(丢丢) 传说院赛要取消 ? ... 这么菜不出去丢人也好吧~ #include<stdi ...

  3. HDU 2089 数位dp/字符串处理 两种方法

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  4. 不要62(HDU 2089数位dp入门)

    题意:统计区间 [a,b] 中不含 4 和 62 的数字有多少个. 分析:dp[i][f]数字表示不含 4 和 62的前提下,剩余长度为 len ,首位是否为 6 的个数. #include < ...

  5. HDU - 2089 数位DP 初步

    中文题目,不要62和4 从高位往低位DP,注意有界标志limit的传递 dp2记忆有界情况下的计数结果,据说用处不大 我所参考的入门文章就是半搜索(有界)半记忆(无界)的 进阶指南中提出dfs维度有多 ...

  6. 杭电hdu 2089 数位dp

    杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍 ...

  7. hdu 2089 数位dp入门题

    #include<stdio.h> //dp[i][0]代表不存在不吉利数字 //dp[i][1]代表不存在不吉利数字但是以2开头 //dp[i][2]代表存在不吉利数字 #define ...

  8. hdu 4507 数位dp(求和,求平方和)

    http://acm.hdu.edu.cn/showproblem.php?pid=4507 Problem Description 单身! 依旧单身! 吉哥依旧单身! DS级码农吉哥依旧单身! 所以 ...

  9. hdu 4352 数位dp + 状态压缩

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. python 函数参数 *a **kw

    f(name='a') name >>> def f(*a,**kw): print a for i in kw: print i >>> f([1,2],n='a ...

  2. C# 类库调试 启动外部程序无法调试

    无法调试进程 test.exe [17936] 中的某些代码.请参阅下面的状态信息. IntelliTrace 代码失败(0x80131534).    Managed (v4.6.v4.5.v4.0 ...

  3. 06-padding(内边距)

    padding padding:就是内边距的意思,它是边框到内容之间的距离 另外padding的区域是有背景颜色的.并且背景颜色和内容的颜色一样.也就是说background-color这个属性将填充 ...

  4. MFC+OpenGL基础绘制<转>

    转载地址:https://blog.csdn.net/u013232740/article/details/47904115 ------------------------------------- ...

  5. 用python实现一个简单的服务器

    打开命令行工具,输入: python3 -m http.server 8000(端口可以自己定) 通过访问:http://ip:8000/,就能给别人快速分享文件了.

  6. 剑指offer例题——裴波那契数列

    编程题:大家都知道裴波那契数列,现在要求输入一个整数n,请你输出裴波那契数列的第n项(从0开始,第0项为0).n<=39 public class Solution { public int F ...

  7. linux下mysql开启远程访问权限 防火墙开放3306端口

    linux下mysql开启远程访问权限 防火墙开放3306端口 转载  2017-01-21   作者:JAVA-ANDROID 这篇文章主要为大家详细介绍了linux下mysql开启远程访问权限,防 ...

  8. Django后台邮箱配置

    Django可以通过发送邮件的方式找回密码,具体细节可以看Django的文档,这里只介绍在settings.py中如何正确进行邮箱的相关配置. 网上很多教程都说了需要在settings.py里添加如下 ...

  9. JS实现简单的运行代码 & 侧边广告

    /* JS实现简单的运行代码功能 */<!doctype html> <html> <head> <meta charset="utf-8" ...

  10. 使用jQuery+huandlebars遍历展示对象中的数组

    兼容ie8(很实用,复制过来,仅供技术参考,更详细内容请看源地址:http://www.cnblogs.com/iyangyuan/archive/2013/12/12/3471227.html) & ...