数位dp浅谈(hdu3555)
数位dp简介:
数位dp常用于求区间内某些特殊(常关于数字各个数位上的值)数字(比如要求数字含62,49);
常用解法:
数位dp常用记忆化搜索或递推来实现;
由于记忆化搜索比较好写再加上博主比较蒟,所以本文基本只介绍用记忆化搜索实现的数位dp;
记搜写法:
一般记搜写法会暴力搜索每个数的每一位,如果满足特征就加入答案;
而搜索中或搜完后用一个dp数组来存某一区间的特殊数的数量,防止多次重复搜索TLE;
空口说比较苍白无力,举个例子:比如要在1到r中找含49(4和9要连在一起)的特殊数的数量;
搜索时,传递当前要填的数字在数中的位置(pos),上一个填的数值(pre),之前有没有出现49(have),以及填的数有没有限制(limit);
pos用来观察这个数有几位,有没有达到范围;
pre用来判断之前的数是不是4,从而来判断如果当前位填9,是否能出现49
have用记录是否出现 49,在搜的过程中就可以记录特殊数的数量;
limit的作用是防止数过大超过范围(具体操作见下文例题);
dp[pos][pre]存当当前要填的数的位置为pos,上一个数为pre时特殊值的数量;
例题(hdu3555):
题目大意是给出n,给出n个范围1—r,输出每个范围中含49的数的数量
思路就是上面的例子,这里仔细介绍一下limit的用法;
比如r=1234,当pos=3(pos=1时是个位,从第一位开始搜),如果pre=1,那么这一位就只能填0—2了,limit就是记录之前填的数和上界是否相同,而传递也很简单,如果limit=true而且当前要填的数等于给定范围的pos位上的数时,limit仍然是true,否则就是false;
注意!
1、数位dp基本上的题都要开long long,不然暴力就能过了;
2、具体题目时要注意dp的含义防止重复加;
下面附上丑陋的代码:
#include<cstdio>
using namespace std;
#define int long long
const int MAXN=;
int n,r,t,digit[MAXN],dp[MAXN][MAXN];
//digit是上界各个位置的数
//dp记录搜过的值
int dfs(int pos,int pre,bool limit)
//我这里的记搜和上面讲的略有不同,求的是不满足条件的数,如果出现49了就不继续做
//最后答案就是上界减去搜出来的数值
//这样可以在记搜时去除一维,加快一点速度
{
if(pos==) return ;
if(!limit&&dp[pos][pre]!=)
//这里的!limit是因为如果当前填的数是有范围的(不能大于上界),就不满足一般的规律
{
return dp[pos][pre];
}
int up=;
if(limit) up=degit[pos];
//如果有限制就把上界设为范围的值
int ans=;
for(int i=;i<=up;++i)
if(pre==&&i==)
continue;
//满足条件就跳出
else
{
ans+=dfs(pos-,i,limit&&(i==digit[pos]));
}
if(!limit)
//和上面的!limit同一个道理
{
dp[pos][pre]=ans;
}
return ans;
}
void solve(int x)
{
t=;
int xx=x;
while(x>)
{
++t;
digit[t]=x%;
x=x/;
}
printf("%lld\n",xx-dfs(t,,)+);
}
main()
{
scanf("%lld",&n);
for(int i=;i<=n;++i)
{
scanf("%lld",&r);
solve(r);
}
}
数位dp浅谈(hdu3555)的更多相关文章
- 浅谈数位DP
在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...
- 数位dp真·浅谈 By cellur925
预警:由于是从$Vergil$学长那里和$Mathison$大神那里学来的,所以清一色记忆化搜索!qwq 巨佬的数位dp讲解(未来的咕咕日报头条): https://www.luogu.org/blo ...
- 浅谈状态压缩DP
浅谈状态压缩DP 本篇随笔简单讲解一下信息学奥林匹克竞赛中的状态压缩动态规划相关知识点.在算法竞赛中,状压\(DP\)是非常常见的动规类型.不仅如此,不仅是状压\(DP\),状压还是很多其他题目的处理 ...
- hdu3555 数位dp
Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Subm ...
- hdu3555 Bomb (记忆化搜索 数位DP)
http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others) Memory ...
- hdu---(3555)Bomb(数位dp(入门))
Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submi ...
- hdu3555 Bomb 数位DP入门
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 简单的数位DP入门题目 思路和hdu2089基本一样 直接贴代码了,代码里有详细的注释 代码: ...
- 【Hdu3555】 Bomb(数位DP)
Description 题意就是找0到N有多少个数中含有49. \(1\leq N \leq2^{63}-1\) Solution 数位DP,与hdu3652类似 \(F[i][state]\)表示位 ...
- 【hdu3555】Bomb 数位dp
题目描述 求 1~N 内包含数位串 “49” 的数的个数. 输入 The first line of input consists of an integer T (1 <= T <= 1 ...
随机推荐
- 《React+Redux前端开发实战》笔记1:不涉及React项目构建的Hello World案例
本小节实现一个不涉及项目构建的Hello World. [React的第一个Hello World网页] 源码地址:https://jsfiddle.net/allan91/2h1sf0ky/8/ & ...
- 深入理解java:2. 多线程机制
引言 很多人都对其中的一些概念不够明确,如同步.并发等等,让我们先理清一些概念,以免产生误会. 多线程:指的是这个程序(一个进程)运行时,产生了不止一个线程. 并行与并发: 并行:多个cpu实例或者多 ...
- if——while表达式详解
①while循环的表达式是循环进行的条件,用作循环条件的表达式中一般至少包括一个能够改变表达式的变量,这个变量称为循环变量 ②当表达式的值为真(非零)(非空)时,执行循环体:为假(0)时,则循环结束 ...
- [DS+Algo] 003 一维表结构 Python 代码实现
接上一篇 前言 本篇共 3 个代码实现 严格来说 code1 相当于模仿了 Python 的 list 的部分简单功能 code2 与 code3 简单实现了"循环单链表"与&qu ...
- 关于golang select的用法
1 go的信道 1.1 什么是信道 信道可以理解为go协程之间进行通信的通道. 1.2 信道的声明 所有的信道都关联一个类型,一旦关联了类型,该信道就只能传输该类型的数据,传输其它类型的数据的话就是非 ...
- c++构造顺序
1. 静态成员最先构造,按照静态成员初始化顺序,不是类里面的声明顺序 2. 父类构造 3. 非静态成员构造,按照类成员声明顺序,不是逗号初始化成员顺序 4. 自身构造函数 Demo: class Te ...
- Python 数据分析:Pandas 缺省值的判断
Python 数据分析:Pandas 缺省值的判断 背景 我们从数据库中取出数据存入 Pandas None 转换成 NaN 或 NaT.但是,我们将 Pandas 数据写入数据库时又需要转换成 No ...
- Docker Compose 部署 Redis 及原理讲解 | 懒人屋
原文:Docker Compose 部署 Redis 及原理讲解 | 懒人屋 Docker Compose 部署 Redis 及原理讲解 4.4k 字 16 分钟 2019-10-1 ...
- spring boot 枚举使用的坑
java 枚举的功能挺多,但是坑更多,使用的时候要注意.如下面这个枚举. @Getter @AllArgsConstructor public enum EnumExpenseType impleme ...
- react找到对象数组中指定的值
找到对象数组中指定的值var array = [ { label: "Custom", value: "0" }, ...