数位DP是我的噩梦。

现在初三了,却没AC过数位DP的题目。

感觉数位DP都是毒瘤……

题目

hdu不用登录也可以进去,所以就不把题目copy到这里来了。

题目大意

求区间[n,m][n,m][n,m]中,不含有444和626262的数的个数。


解析

数位DP的难点主要在于不能出界。

因为这个东西,我被卡了不知道多少年……

先不要想出界,那么显然,状态可以这么设:

设fi,jf_{i,j}fi,j​表示做到第iii位,并且这一位为jjj的方案数。

方程显然

	if (j!=4 && !(j==6 && k==2))
f[i][j]+=f[i-1][k];

所以我们可以先预处理出fff数组。

对于区间[n,m][n,m][n,m],类似前缀和,我们可以将其转化成求[1,x][1,x][1,x]。

接下来就是最毒瘤的出界问题了。

比如x=314x=314x=314

那么f2,0,f2,1,f2,2f_{2,0},f_{2,1},f_{2,2}f2,0​,f2,1​,f2,2​可以计入贡献,因为前面的数字不管怎么变,都必定不会出界。

但是f2,3f_{2,3}f2,3​是不可以直接计入贡献的。

所以咋办?

我们可以继续下一位,计算x=14x=14x=14时的贡献,当然,要记录一下上一次最后的数,在计入贡献前要先判断是否合法。

因为我们计算的都是小于xxx的贡献,所以在计算之前我们要先将xxx加一

具体见下面的代码。


代码

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define MAXM 1000000
int n,m;
int f[10][10];
int pow10[10];
void init();
int getans(int);
int main(){
pow10[0]=1;
for (int i=1;i<=9;++i)
pow10[i]=pow10[i-1]*10;
init();
do{
scanf("%d%d",&n,&m);
if (n==0 && m==0)
return 0;
printf("%d\n",getans(m)-getans(n-1));
}
while (1);
return 0;
}
void init(){
for (int i=0;i<=9;++i)
f[0][i]=(i!=4);//i!=4时就为1
for (int i=1;i<=6;++i)
for (int j=0;j<=9;++j){
if (j==4)
continue;
for (int k=0;k<=9;++k)
f[i][j]+=f[i-1][k];
if (j==6)
f[i][j]-=f[i-1][2];//将j==6和k==2不合法的贡献减掉
}
}
int getans(int x){
x++;//因为下面的算法计算的是小于x的贡献,所以要先x++
if (x<0)
return 0;
int res=0,w=log10(x);//w为x的位数
for (int i=w,lst=0;i>=0;--i){
int s=x/pow10[i]%10;//求出第i为的贡献
for (int j=0;j<s;++j)
res+=f[i][j];//将小于s的贡献全部加上(因为前面的数怎么变都不可能越界)
if (lst==6 && 2<s)
res-=f[i][2];//同样将不合法的贡献减去
if (s==4 || lst==6 && s==2)//如果这个时候出现不合法的情况,那么后面的都是不合法的,直接退出
break;
lst=s;
}
return res;
}

总结

数位DP最难的地方就是判断出界。

所以我们应该从高位到低位逐个判断。

保证范围小于边界。

数位DP入门题——[hdu2089]不要62的更多相关文章

  1. HDU 2089 不要62【数位DP入门题】

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

  2. HDU 2089 - 不要62 - [数位DP][入门题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...

  3. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  4. 数位DP入门题

    站点一览: hdu 2089"不要62" hdu 4734"F(X)" poj 3252"Round Numbers" hdu 3709&q ...

  5. 数位DP入门(A - 不要62 HDU - 2089 &&B - Bomb HDU - 3555 )

    题目链接:https://cn.vjudge.net/contest/278036#problem/A 具体思路:对于给定的数,我们按照位数进行运算,枚举每一位上可能的数,在枚举的时候需要注意几个条件 ...

  6. hdu 2089 数位dp入门题

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

  7. hdu3555 Bomb (数位dp入门题)

    Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submi ...

  8. xbz分组题B 吉利数字 数位dp入门

    B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...

  9. 数位dp入门 hdu2089 不要62

    数位dp入门 hdu2089 不要62 题意: 给定一个区间[n,m] (0< n ≤ m<1000000),找出不含4和'62'的数的个数 (ps:开始以为直接暴力可以..貌似可以,但是 ...

随机推荐

  1. thinkphp 分布式数据库支持

    ThinkPHP内置了分布式数据库的支持,包括主从式数据库的读写分离,但是分布式数据库必须是相同的数据库类型. 配置DB_DEPLOY_TYPE 为1 可以采用分布式数据库支持.如果采用分布式数据库, ...

  2. hdu6607 min25筛+杜教筛+伯努利数求k次方前缀和

    推导过程类似https://www.cnblogs.com/acjiumeng/p/9742073.html 前面部分min25筛,后面部分杜教筛,预处理min25筛需要伯努利数 //#pragma ...

  3. Delphi利用Windows GDI实现文字倾斜

    Delphi利用Windows GDI实现文字倾斜 摘要 Delphi利用Windows GDI实现文字倾斜 procedure TForm1.FormPaint(Sender: TObject);v ...

  4. bzoj 1196: [HNOI2006]公路修建问题(二分+贪心)

    传送门 解题思路 看到最大,肯定要先想二分答案.二分之后首先从小到大枚举\(k\)个小于\(lim\)的所有一级公路,然后用并查集连到一起,然后就在剩下的里面从小到大找n-1-k个二级公路,模仿最小生 ...

  5. javascript和jquery

    JavaScript 1.概述 JavaScript是一种基于对象和事件驱动,并具有安全性能的脚本语言. 2.语法 HTML 中的脚本必须位于 <script> 与 </script ...

  6. Vue 中 computed ,watch,methods 的异同

    methods,watch和computed都是以函数为基础的. computed 和 watch 都可以观察页面的相应式数据的变化.当处理页面的数据变化时,我们有时候很容易滥用watch, 而通常更 ...

  7. 豌豆荚Redis集群方案:Codis

    Codis简介 Codis是一个分布式Redis解决方案,对于上层的应用来说,连接到CodisProxy和连接原生的RedisServer没有明显的区别(不支持的命令列表),上层应用可以像使用单机的R ...

  8. <每日一题>算法题:小球的下落距离

    题目:小东和三个朋友一起在楼上抛小球,他们站在楼房的不同层,假设小东站的楼层距离地面N米,球从他手里自由落下,每次落地后反跳回上次下落高度的一半,并以此类推知道全部落到地面不跳,求4个小球一共经过了多 ...

  9. 【转载】Kafka介绍及升级经验分享

    http://blog.talkingdata.net/?p=3165 背景 当时的现状:开始使用Kafka的时候,使用的版本是0.7.2,当时的目的是为了替代kestrel,主要是使用Kafka来做 ...

  10. Linux 下 cs8900a 的移植说明

    为 cs8900a 建立编译菜单 1. 拷贝到文件 把 cs8900a 的压缩包拷贝到 arm 用户下的 dev_home/localapps/ [arm@localhost localapps]$ ...