数位dp介绍
不了解dp的可以先看一下dp
数位dp含义:
数位:一个数有个位,十位,百位,千位等等,数的每一位都是数位。
数位dp归为计数dp,是在数位上进行操作的dp。
数位dp的实质是一种快速枚举的方式,它满足dp的性质,然后进行记忆化搜索。
用途:
有两个数,两个数范围很大(例如1e9,甚至更大),求这两个数符合限定条件的个数。纯暴力不行,就要用数位dp。
例子:求从0到n,(n为2^32-1),(条件)求包含49的数有多少;
思路or具体实现:
n为2^32-1,数位其实只有20位,枚举数位,就不会超时。
dp[shuwei][diaojian]。dp的第一维通常是数位,后面的几维根据题目条件来设定。上面给的例子只用了一维。
控制上界枚举,从最高位往下枚举。用记忆化搜索来做,抛开循环后转移状态能更加随意,大部分数位和动态规化的题都可随意切换。搜索与循环异曲同工之妙,但前者更易转移状态,在限制较多的情况下被大部分人喜爱。
例题:Bomb
思路 :数位dp=dfs+记忆化搜索。
需要注意上限即题目所给范围的预处理,本题用digtis[20] 数组,存储上限的数位,最好用一个函数来处理,比如solve(sum),处理时,对上限的数位总数拿一个变量进行存储,比如k或len。
在dfs中用 limit (有些题解是top)判定上限,dfs(len,条件,limit);
dfs执行数位dp,在搜索时用了 up_bound=(limit?digit[len]:9); 来标记上限,同时用cnt来存储满足的条件的数量,然后更新dp数组,更新时要满足if(!limit),到达上界,状态不完整。
在dfs中对条件的处理,需要根据题意去确定,每个题目不一样。
是否顶着上界,每层确定这一位选啥,判断是否和上一位冲突,全部确定完了方案数+1。
由于顶着上界是比较特殊的情况,所以这类答案直接一层层搜索出答案,不用记忆化,其他(不顶着上界)的情况用dp[][] 直接返回数量。
有些题目需要最后算一下最高位为0的情况。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL; int digit[]; //储存上界的每个数位
LL dp[][]; //统计没有49的总数 //if4它的上一位和当前位是否是4
//len 记录当前数位,从高位往下搜索
//limit 上一位是否是上界 LL dfs(int len, bool if4, bool limit){
if(len==) return 1ll; //个位的时候,有一个分支。
if(!limit && dp[len][if4]) return dp[len][if4];
//没到达上界并且数位已经统计过,直接返回数量。 LL cnt=,up_bound=(limit?digit[len]:);
//标记数位的上界 //对整个数位进行记忆化搜索
for(int i=;i<=up_bound;++i){
if(if4&&i==) continue;//碰到49不加入。
cnt+=dfs( len-, i==,limit && i==up_bound);
//向下搜索,判断上一位是否为4,上一位是否到达上界,当前位是否到上界。
}
if(!limit) dp[len][if4]=cnt; //到达上界是状态不完整,不更新dp
return cnt;//直接返回本次搜索结果,加入到最后结果中
} LL solve(LL num) //num是上界这个数
{
int k=;//记录数位个数。
while(num)
{
digit[++k]=num%;
num/=;
}
return dfs(k,false,true);
} int main(){
int t;
cin>>t;
while(t--)
{
LL n;
cin>>n;
cout<<n+-solve(n)<<endl;
}
return ;
}
数位dp详解
数位dp介绍的更多相关文章
- 数位DP入门:(bzoj1833+3209)
//我是来看文章创建时间的= = 膜拜了一下蔡大神.... 人生第一道自己写的数位DP...好吧以前是看题解然后也不知道为什么就过了的>_< 虽然说现在还是只会裸题= = 数位DP介绍: ...
- 数位DP入门Ural1057
CF一战让我觉得很疲倦,所以今天感觉很慢. 昨天解D题时候,因为太累,根本连题目都没看,今天看了之后感觉不会做,听闻是数位DP问题. 有某神说过,DP的功力建立在刷过的题上,我真的毫无功力可言. 介绍 ...
- 动态规划——数位dp
通过先前在<动态规划——背包问题>中关于动态规划的初探,我们其实可以看到,动态规划其实不是像凸包.扩展欧几里得等是具体的算法,而是一种在解决问题中决策的思想.在不同的题目中,我们都需要根据 ...
- ural 1057(数位dp)
数位dp题,关键是用树的思维去考虑. 对于一个数字X,要是能表示成K个B的不同次幂,等价于X在B进制下有且只有K个位上面的数字为一,其他位上的数字都为0. 具体读者可以去参考,国家集训队李聪的论文,里 ...
- hdu_4352_XHXJ's LIS(数位DP+状态压缩)
题目连接:hdu_4352_XHXJ's LIS 题意:这题花大篇篇幅来介绍电子科大的一个传奇学姐,最后几句话才是题意,这题意思就是给你一个LL范围内的区间,问你在这个区间内最长递增子序列长度恰为K的 ...
- 数位dp 的简单入门
时间紧张,就不讲那么详细了. 之前一直被深搜代码误解,以为数位dp 其实就是记忆化深搜...(虽说爆搜确实很舒服而且还好想) 但是后来发现数位dp 的标准格式其实是 预处理 + dp ...... 数 ...
- hdu 4352 "XHXJ's LIS"(数位DP+状压DP+LIS)
传送门 参考博文: [1]:http://www.voidcn.com/article/p-ehojgauy-ot.html 题解: 将数字num字符串化: 求[L,R]区间最长上升子序列长度为 K ...
- 数位DP详解
算法使用范围 在一个区间里面求有多少个满足题目所给的约束条件的数,约束条件必须与数自身的属性有关 下面用kuangbin数位dp的题来介绍 例题 不要62 题意:在一个区间里面求出有多少个不含4和6 ...
- hdu 2089 数位dp
链接:https://vjudge.net/problem/23625/origin 中文,题目不用说了. 其实这题的数据很小,所以直接暴力也可以过,但是还是要学会数位dp,因为并不是每一题的数据都会 ...
随机推荐
- js图片随机切换
使用js做到随机切换图片 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...
- MarkDown的常用语法
个人比较喜欢Markdown的语法,常用来做一些笔记,下面就简单介绍一下它的语法. 概览 宗旨 Markdown 的目标是实现「易读易写」. 可读性,无论如何,都是最重要的.一份使用 Markdown ...
- Linux Cannot allocate memory问题
查找了一下相关文档,发现这个错误的含义其实就是像它自己说的,没法分配内存了. The problem is inherent with the way Java allocates memory wh ...
- 七牛云图片存储---Java
一.新建存储空间 到七牛云官网注册一个账号 新建一个存储空间 到个人中心获取秘钥 二.新建Java项目 1.pom.xml配置 <dependency> <groupId>co ...
- Chrome插件开发(四)
在前面我们编写了三个比较实用的插件,在实际工作中,我们还会使用很多其他的插件,比如掘金,Pocket之类的,我们可能需要经常启用或禁用插件或者删除插件,如果每次都要点到更多工具->扩展程序中去做 ...
- [考试反思]0812NOIP模拟测试18:稀释
[]200 [4]190[5]180 [6]170[7]150 [11]140[16]130[19]120[24]100 有些事情,看淡了,也就简单了. 连续爆炸之后,没什么感觉了. 把态度放正,把结 ...
- NOIP模拟 30
补坑,很多都忘了. T1 树 像我这种人都能考场A掉当然是道水题辣 求出每条有向边的期望就好了 T2 回文串 当时毫无思路,暴力写挂. 首先把B转过来,那么都变成后缀的前缀拼起来 对于每一个LCP,他 ...
- 清空 npm 缓存
清空 npm 缓存 npm cache clean -f
- re模块的基本使用
目录 re模块 常用元字符 特殊构造 贪婪模式 非贪婪模式 re的常用函数 re模块补充 关于re模块必须知道的知识点 re模块 re模块 , 即正则表达式 , 本身是一种小型的.高度专业化的编程语言 ...
- Kubernetes(k8s)集群安装
一:简介 二:基础环境安装 1.系统环境 os Role ip Memory Centos 7 master01 192.168.25.30 4G Centos 7 node01 192.168.25 ...