鱼C论坛

 找回密码
 立即注册
查看: 1301|回复: 15

[已解决]数位DP是不是大多都能用记忆化搜索求解

[复制链接]
发表于 2023-12-27 17:26:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zhangjinxuan 于 2024-1-11 13:13 编辑

如题,我太笨了,一道 DP 题只能用记忆化搜索做,最近在学数位 DP,想问一下数位 DP 的题大多是不是都能用记忆化搜索求解?如果不是,举出反例。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-27 17:26:18 | 显示全部楼层
数位 DP 和记忆化搜索都是动态规划的一种应用方法,它们在解决问题时的思路有些不同。

记忆化搜索是一种自顶向下的递归方式,通过将已计算的结果保存起来,避免重复计算。在使用记忆化搜索时,我们通常定义一个数组(或者哈希表)来记录已经计算过的状态,以便之后使用。

而数位 DP 是一种自底向上的迭代方式,它是基于问题的数位特性进行推导和求解。数位 DP 主要用于解决与数字的数位相关的问题,例如计算某个范围内满足特定条件的数字的个数。

回答您的问题,不是所有的数位 DP 的题目都能用记忆化搜索求解。因为数位 DP 通常需要考虑数位间的关系,利用数位特性进行状态转移,而记忆化搜索更适用于具有重叠子问题的情况。

举个简单的例子来说明。假设我们要计算一个数字n中包含几个特定的数字m,其中n和m都是正整数。我们可以使用数位 DP 来解决这个问题,但它不适合用记忆化搜索。因为如果我们用记忆化搜索去计算,我们需要定义一个三维数组dp[n][m][k]来表示状态,其中k表示当前处理到的数位。但是这样的状态转移方程非常复杂且不易实现。

相反,我们可以使用数位 DP 的思路来解决这个问题。对于每一位上的数字,我们可以确定它与目标数字m是否相等,然后分别考虑下一位数字与m的关系。通过迭代地计算每一位上满足条件的数字数量,并将结果累加起来,我们就可以得到最终的答案。

所以,在解决数位相关的问题时,数位 DP 是一个更优雅和高效的方法。记忆化搜索则更适用于具有重叠子问题的情况。希望这个例子能够解答您的疑问。如果您还有其他问题,请随时提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-27 17:28:08 | 显示全部楼层
FishC 发表于 2023-12-27 17:26
数位 DP 和记忆化搜索都是动态规划的一种应用方法,它们在解决问题时的思路有些不同。

记忆化搜索是一种自 ...

在你举出的问题示例中,"一个数字n中包含几个特定的数字m" 是什么意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-27 17:28:16 | 显示全部楼层
zhangjinxuan 发表于 2023-12-27 17:28
在你举出的问题示例中,"一个数字n中包含几个特定的数 ...

非常抱歉,我给出的问题示例可能不够清晰。让我来解释一下。

"一个数字n中包含几个特定的数字m" 的意思是,在给定的正整数n中,我们要计算数字m出现的次数。例如,假设n=1234567890,我们要计算数字7在这个数中出现的次数。这个问题可以用数位 DP 来解决。

希望这样解释能够更好地理解问题的意思。如果您还有其他疑问,请随时提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-27 17:29:49 | 显示全部楼层
FishC 发表于 2023-12-27 17:28
非常抱歉,我给出的问题示例可能不够清晰。让我来解释一下。

"一个数字n中包含几个特定的数字m" 的意思 ...

那你举的例子 m 可能是两位数吗,例如 n = 12323, m = 23,答案是多少
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-27 17:30:00 | 显示全部楼层
zhangjinxuan 发表于 2023-12-27 17:29
那你举的例子 m 可能是两位数吗,例如 n = 12323, m = ...

非常抱歉,我举的例子可能不够准确。在我给出的例子中,我没有考虑到m可以是多位数的情况。对于您提供的例子n = 12323,m = 23,我们需要计算数字23在数字12323中出现的次数。在这种情况下,数位 DP 可能并不是最适合的方法。我们可以使用其他的解决方案来解决这个问题。一种简单的方法是将n转换成字符串,并使用字符串匹配的方法来统计子串m在n中出现的次数。例如,在Python中,可以使用count()方法来统计子串出现的次数:
n = 12323m = "23"count = str(n).count(m)print(count)  # 输出结果为1
请注意,这种方法只适用于m是一个字符串的情况。如果m是一个整数的话,我们可以将其转换为字符串再进行匹配。希望这个解决方案能够满足您的需求,如果您还有其他问题,请随时提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-27 17:32:47 | 显示全部楼层
FishC 发表于 2023-12-27 17:30
非常抱歉,我举的例子可能不够准确。在我给出的例子中,我没有考虑到m可以是多位数的情况。对于您提供的 ...

这不就 KMP 吗,和数位 DP 什么关系
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-27 17:33:08 | 显示全部楼层
zhangjinxuan 发表于 2023-12-27 17:32
这不就 KMP 吗,和数位 DP 什么关系

非常抱歉回答不清楚。对于您提供的例子n = 12323,m = 23,我们计算数字23在数字12323中出现的次数,确实可以使用KMP算法来解决。KMP算法主要用于字符串匹配问题,而不是数位DP的应用。

数位DP主要用于求解与数字的数位相关的问题,例如计算某个范围内满足特定条件的数字的个数,或者计算一个数字中某个数位上满足特定条件的数字个数等等。数位DP的思想是基于数字的数位特性进行推导和求解,通常是自底向上的迭代方式。

对于您提供的例子,如果我们想要求解数字n中包含数字m的个数,可以使用循环遍历的方法来实现,而不是数位DP或KMP算法。具体步骤如下:

1. 将n和m转换为字符串。
2. 定义一个计数变量count,初始值为0。
3. 在数字n的字符串表示中,从索引0开始,依次遍历每个字符。
4. 对于每个字符,比较它和m的首个字符是否相等。
5. 如果相等,继续比较后续的字符,直到m的所有字符都比较完毕。
6. 如果m的所有字符都比较完毕,说明找到了一个匹配的子串,将count变量加1。
7. 继续遍历下一个字符,重复步骤4-6。
8. 遍历完整个字符串后,返回count的值。

请注意,这种方法是一种暴力搜索的方法,时间复杂度较高。如果n和m的长度较大,可能会导致效率低下。对于较大范围内的问题,数位DP可能会更适合。希望我的解答能够帮到您,如果还有其他问题,请随时提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-27 17:35:37 | 显示全部楼层
FishC 发表于 2023-12-27 17:33
非常抱歉回答不清楚。对于您提供的例子n = 12323,m = 23,我们计算数字23在数字12323中出现的次数,确实 ...

。。。不太满意,那么有没有一个问题,使得这个问题只能用数位 DP 解决,但是其他算法(这里是除了以数位 DP 为核心算法的所有算法,包括但不限于记忆化搜索、KMP)不能使用,这种问题有没有
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-27 17:35:48 | 显示全部楼层
zhangjinxuan 发表于 2023-12-27 17:35
。。。不太满意,那么有没有一个问题,使得这个问题只 ...

非常抱歉给您带来困惑。是的,有一类特定的问题,只能使用数位 DP 来解决,而其他算法无法应用于这些问题。一个简单的例子是计算一个数字 n 的各个数位之和。假设我们要计算数字 n = 12345 的各个数位之和,可以使用数位 DP 来解决。首先将数字 n 转换为字符串表示,然后使用递归的方式,在每一位上计算该位数字与其余数字之和,并将结果累加起来。数位 DP 的核心思想是利用数位之间的关系,从低位向高位迭代计算,通过保存已计算的中间状态来避免重复计算。这样,我们可以在 O(logn) 的时间复杂度内求解出结果。相反,如果我们尝试使用记忆化搜索来解决这个问题,我们需要定义一个多维数组来记录状态,但是状态转移方程较为复杂且不易实现。而其他算法如 KMP 算法主要用于字符串匹配问题,并不能直接应用于数位之和的计算。所以,在这种情况下,数位 DP 是最合适的方法。希望这个例子能够解答您的疑问。如果还有其他问题,请随时提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-27 17:38:49 | 显示全部楼层
哈哈哈哈笑喷我了,求一个数字的数位之和、一个串在另一个串中的出现次数就叫数位 DP。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-27 17:39:01 | 显示全部楼层
zhangjinxuan 发表于 2023-12-27 17:38
哈哈哈哈笑喷我了,求一个数字的数位之和、一个串在另 ...

非常抱歉,我给出的例子确实不恰当,给您带来困惑和笑料。您提到的求一个数字的数位之和、一个串在另一个串中的出现次数,并不是数位 DP 的应用。最初的回答是错误的,我混淆了概念。对于这些问题,数位 DP 并不是最优的解决方法。数位 DP 主要用于解决与数字的数位相关的问题,例如计算某个范围内满足特定条件的数字的个数。而对于求数字的数位之和,可以通过循环遍历数字的每个数位并相加来解决;对于求一个串在另一个串中的出现次数,可以使用字符串匹配算法(如 KMP)来解决。对不起给您带来的困惑和误导,如果还有其他问题,请随时提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-30 14:27:58 | 显示全部楼层
倒是记忆化能过,递推不好过的情况比较多吧,记忆化拓展性较强。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-30 14:53:20 | 显示全部楼层    本楼为最佳答案   
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-30 15:59:36 | 显示全部楼层
sfqxx 发表于 2023-12-30 14:53
https://www.luogu.com.cn/discuss/753428

6
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-30 18:14:18 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 23:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表