Skip to content

服务器托管,北京服务器托管,服务器租用-价格及机房咨询

Menu
  • 首页
  • 关于我们
  • 新闻资讯
  • 数据中心
  • 服务器托管
  • 服务器租用
  • 机房租用
  • 支持中心
  • 解决方案
  • 联系我们
Menu

数位DP?记忆化罢了!

Posted on 2023年9月18日2023年9月18日 by hackdl

我看了半天的数位 DP,DP 没学会,人倒是麻了。

解决什么

一般用于求解给你一个区间 ([l,r]),问你其中满足条件的数有多少个。

这种题目还是蛮常见的,我们一般情况下暴力只能拿一少部分分,之前我看着那个 (nle 10^{18}) 是一脸懵逼,这东西 (O(n)) 都过不去,啥高级的东西能 A 啊。

然后就有了今天让我麻了的数位 DP。

思想

题目中给的让我们难以下手,我们不如转化一下:求 ([1,r]) 中符合限制的数并减去 ([1,l-1]) 的数。

这样就好处理多了,当然也可以从 (0) 开始,根据题目而定。

然后我们把要求的 ([1,x]) 区间中的 (x) 给一位一位分解开,然后 dfs 往里面填数。

在分解的时候,我们用一个数组 (a[i]) 来存储从高位到低位(一般是)的数字,来当作填数的限制。

我们在 dfs 的时候,传的参数至少是包含 pos 当前填到第几个数以及 limit 也就是当前点是否有限制,如果有的话,我们在后面遍历当前点填的数的时候直接调用之前的 (a[]) 数组就好了。

当然我们在 dfs 的时候是要记忆化的,不然复杂度直接飙升,我们可以根据题目给的限制条件来把状态相同的归到一类然后存放到数组里面,然后我们就可以在遇到与当前状态相同的时候直接调用记忆化数组来让我们的复杂度变得美丽。

遍历每一个数的时候一般分为两种情况,一个有前导零,一个没有前导零。

P2602 [ZJOI2010] 数字计数

code:

#include 

#define int long long
#define N 20

using namespace std;

int a[N], cnt, f[N][N > L >> R;
	
	for(int i = 0; i 

和前面讲的一样,利用记忆化搜索,注释应该很清楚了吧。

P8764 [蓝桥杯 2021 国 BC] 二进制问题

数位 DP 板子题。

我们设 (f_{i,j}) 为当前从左往右枚举到第 (i) 个数没有枚举时,当前枚举完的 (1) 的个数为 (j) 时的能得到的有 (k) 个 (1) 的个数。

我们用 ? 来表示当前点没有填入,假设我们现在从左往右填,当前的状态是 10101?????,我们 dfs 完以后,直接存入 (f_{6,3}) 里,我们要是再枚举到类似 10011????? 这种的,我们可以发现,后面问号的可能性是一样的,也就是说,他们得到的答案是一样的,那么我们就可以进行记忆化了。

我们对于给定的 (n) 按照其他的数位 DP 一样拆成二进制下的数,将每一位都存放到 (a_{i}) 里,也就是说 (a_{i}) 表示从左往右第 (i) 个数可以填 (1sim a_{i})。

由于这里的情况很少,只有 (0) 和 (1),所以可以直接展开循环。

code:

#include 

#define int long long
#define N 100

using namespace std;

int n, k, a[N], f[N][N];//枚举到第i个数当前当前j个1的个数 

inline int dfs(int p, int limit, int cnt)
{
	if( cnt > k ) return 0;
	if(! p) return (cnt == k ? 1 : 0);
	if(! limit && f[p][cnt] != -1) return f[p][cnt];
	int res = 0, flag = (limit ? a[p] : 1);
	res += dfs(p - 1, limit && flag == 0, cnt);
	if(flag) res += dfs(p - 1, limit && flag == 1, cnt + 1);
	if (! limit) f[p][cnt] = res;
	return res;
}

inline int fx(int x)
{
	memset(f, -1, sizeof f);
	int len = 0;
	while(x) a[++ len] = (x & 1), x >>= 1;
	return dfs(len, 1, 0);
}

signed main()
{
	cin >> n >> k;
	cout 

服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net

相关推荐: 提高 Java 中锁的性能的技巧

我们努力为自己的产品所遇到的问题思考解决办法,但在这篇文章中我将给大家分享几种常用的技术,包括分离锁、并行数据结构、保护数据而非代码、缩小锁的作用范围,这几种技术可以使我们不使用任何工具来检测死锁。 锁不是问题的根源,锁之间的竞争才是 通常在多线程的代码中遇到…

Related posts:

  1. 阿里云ERP托管费用分析
  2. 交易所托管服务器类型解析
  3. 大带宽服务器租用有哪些优势好处
  4. 香港托管服务器:价格厚道,受欢迎
  5. 探究服务器租用的最低价格

服务器托管,北京服务器托管,服务器租用,机房机柜带宽租用

服务器托管

咨询:董先生

电话13051898268 QQ/微信93663045!

上一篇: mysql索引调优
下一篇: SpringBoot ( 一 ) 搭建项目环境 1.搭建环境

最新更新

  • TCP长连接短连接
  • 1.4. 运算符与表达式
  • 网络安全(黑客)自学
  • 软件设计模式系列之九——桥接模式
  • ICL7106芯片的特性、应用与重要性 | 百能云芯

随机推荐

  • 云原生背景下如何配置 JVM 内存
  • ChatGpt 能成为恋爱大师吗?
  • 杭州服务器托管业务工资分析报告
  • 申请云服务器租用注册流程详解
  • 高效稳定的江苏三线服务器托管服务

客服咨询

  • 董先生
  • 微信/QQ:93663045
  • 电话:13051898268
  • 邮箱:dongli@hhisp.com
  • 地址:北京市石景山区重聚园甲18号2层

友情链接

  • 服务器托管
  • 机房租用托管
  • 服务器租用托管
©2023 服务器托管,北京服务器托管,服务器租用-价格及机房咨询 京ICP备13047091号-8