数位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 ...
随机推荐
- LeetCode.872-叶子值相等的树(Leaf-Similar Trees)
这是悦乐书的第334次更新,第358篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第204题(顺位题号是872).考虑二叉树的所有叶子,从左到右的顺序,这些叶子的值形成叶 ...
- ubuntu/如何启动、关闭和设置ubuntu防火墙
由于LInux原始的防火墙工具iptables过于繁琐,所以ubuntu默认提供了一个基于iptable之上的防火墙工具ufw. ubuntu 9.10默认的便是UFW防火墙,它已经支持界面操作了.在 ...
- 红帽学习笔记[RHCSA] 第八课[Nice值、时间同步、RPM与Yum软件安装]
第八课 nice值 什么是nice值 给进程设置的优先级就是nice.nice的范围是-20~20.nice值越小占用的系统资源就越多,就是这个进程不nice. 如何查看nice值 # 使用top命令 ...
- 第六周总结&第四次实验报告
实验四 类的继承 一. 实验目的 (1) 掌握类的继承方法: (2) 变量的继承和覆盖,方法的继承.重载和覆盖实现: 二. 实验内容 三.实验过程 实验代码 package Shiyan4; publ ...
- 简单记事本的基本实现&十四周总结
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...
- (二)inlineCallbacks,同步方式写异步代码
一. 上篇提到了用defered对象注册回调的方式,来处理异步操作,这样大家都知道,实际情况代码很难搞的.因为当业务逻辑复杂后,这边一个异步操作,我们注册一个回调,代码跳到A地方,A里面也有异步操作, ...
- centos7使用kubeadm搭建kubernetes集群
一.本地实验环境准备 服务器虚拟机准备 IP CPU 内存 hostname 192.168.222.129 >=2c >=2G master 192.168.222.130 >=2 ...
- HNUSTOJ-1638 遍地桔子(贪心)
1638: 遍地桔子 时间限制: 1 Sec 内存限制: 128 MB提交: 711 解决: 134[提交][状态][讨论版] 题目描述 为了实验室的发展,队长决定在实验室外面的空地种桔子树.空地 ...
- 0ctf 2017 kernel pwn knote write up
UAF due to using hlist_add_behind() without checking. There is a pair locker(mutex_lock) at delete_n ...
- KMP解决最小循环节问题
# 10035. 「一本通 2.1 练习 1」Power Strings [题目描述] 给定若干个长度 $\le 10^6$ 的字符串,询问每个字符串最多是由多少个相同的子字符串重复连接而成的.如 ...