数位DP入门题——[hdu2089]不要62
数位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的更多相关文章
- HDU 2089 不要62【数位DP入门题】
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 2089 - 不要62 - [数位DP][入门题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...
- 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题
[HDU 3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...
- 数位DP入门题
站点一览: hdu 2089"不要62" hdu 4734"F(X)" poj 3252"Round Numbers" hdu 3709&q ...
- 数位DP入门(A - 不要62 HDU - 2089 &&B - Bomb HDU - 3555 )
题目链接:https://cn.vjudge.net/contest/278036#problem/A 具体思路:对于给定的数,我们按照位数进行运算,枚举每一位上可能的数,在枚举的时候需要注意几个条件 ...
- hdu 2089 数位dp入门题
#include<stdio.h> //dp[i][0]代表不存在不吉利数字 //dp[i][1]代表不存在不吉利数字但是以2开头 //dp[i][2]代表存在不吉利数字 #define ...
- hdu3555 Bomb (数位dp入门题)
Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submi ...
- xbz分组题B 吉利数字 数位dp入门
B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...
- 数位dp入门 hdu2089 不要62
数位dp入门 hdu2089 不要62 题意: 给定一个区间[n,m] (0< n ≤ m<1000000),找出不含4和'62'的数的个数 (ps:开始以为直接暴力可以..貌似可以,但是 ...
随机推荐
- U Must Know The .Net --7
关键字 1 new 创建对象/调用构造函数 隐藏基类成员 new()约束,表明泛型类声明中的任何参数都必须有公共无参构造函数 new 实现多态 1.1 new class:分配内存,调用构造函数实例化 ...
- windows cmd command
////////////////// ===>windows + r //gpedit.msc 用户组策略 ///////////////// ===>cmd //ping www.bai ...
- thinkphp 标签嵌套
模板引擎支持标签的多层嵌套功能,可以对标签库的标签指定可以嵌套. 直线电机价格 系统内置的标签中,volist.switch.if.elseif.else.foreach.compare(包括所有的比 ...
- csps-模拟7980题解
题面:https://www.cnblogs.com/Juve/articles/11712702.html 树: 我太sb了不知道DROT是1,还在sb找根 记录一个fa[]数组,表示x的祖先中第一 ...
- hadoop镜像文件和编辑日志文件
镜像文件和编辑日志文件 1)概念 namenode被格式化之后,将在/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current目录中产生如下文件 edits_ ...
- fiddler设置抓取HTTPS协议数据包
1.打开工具里的选项 2.选择弹窗中的HTTPS选项,如下图进行勾选 3.若浏览器显示不安全链接则需要添加证书 提示如下点击确定证书安装成功,可以查看安装的证书,点击Action 下图即可查看fidd ...
- dart中的typedef <函数别名>
typedef定义如下: typedef 给某一种特定的函数类型起了一个名字,可以认为是一个类型的别名.或者这样理解: 自己定义了一种数据类型,不过这种数据类型是函数类型,按照这种类型实例化后的对象, ...
- csp-s模拟测试87
csp-s模拟测试87 考场状态还可以$T1$我当时以为我秒切,$T2$确认自己思路不对后毅然决然码上,$T3$暴力挂了太可惜了. 03:01:28 03:16:07 03:11:38 140 03: ...
- System.Web.Mvc.HttpPutAttribute.cs
ylbtech-System.Web.Mvc.HttpPutAttribute.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutral, P ...
- C语言进阶学习第二章
本章重点记录指针的各种概念: 1.地址与内容 2.非法的赋值 3.NULL指针:NULL指针作为一个特殊的指针变量,表示不指向任何东西,在对指针进行解引用操作之前,首先必须 确保它并非NULL指针. ...