Questions tagged «dynamic-programming»

关于可以通过组合递归获得的子问题解决方案来解决的问题的问题。


3
确定动态编程的子问题
我已经多次使用动态编程技术,但是今天有一个朋友问我如何定义子问题,我意识到我无法提供客观的正式答案。您如何正式定义要使用动态编程解决的问题的子问题?


4
什么是动态编程?
抱歉,这个问题听起来很愚蠢。 据我所知,使用动态编程构建算法的工作方式如下: 将问题表达为递归关系; 通过备忘或自下而上的方法来实现递归关系。 据我所知,我已经说了有关动态编程的一切。我的意思是:动态编程不会提供工具/规则/方法/定理来表达递归关系,也不会将其转化为代码。 那么,动态编程有什么特别之处呢?除了解决某些问题的模糊方法之外,它还能给您带来什么?

5
动态编程的案例区分:需要示例!
我从事动态编程已有一段时间了。评估动态编程递归的规范方法是创建一个包含所有必要值的表,并将其逐行填充。有关简介,请参见例如Cormen,Leiserson等人:“算法简介”。 我将重点放在二维(逐行填充)的基于表的计算方案上,并研究单元格依存关系的结构,即在计算另一个单元格之前需要完成哪些单元格。我们用表示Γ(i)Γ(i)\Gamma(\mathbf{i})单元格ii\mathbf{i}依赖的单元格的索引集。请注意,ΓΓ\Gamma必须是无周期的。 我从计算出的实际函数中抽象出来,并专注于其递归结构。形式上,如果递归具有以下形式,则我认为它ddd是动态编程 d(i)=f(i,Γ˜d(i))d(i)=f(i,Γ~d(i))\qquad d(\mathbf{i}) = f(\mathbf{i}, \widetilde{\Gamma}_d(\mathbf{i})) 与,〜Γ d(我)= { (Ĵ,d (Ĵ))| Ĵ ∈ Γ d(我)}和˚F一些(可计算)函数,它不使用ð比通过其他〜Γ d。i∈[0…m]×[0…n]i∈[0…m]×[0…n]\mathbf{i} \in [0\dots m] \times [0\dots n]Γ˜d(i)={(j,d(j))∣j∈Γd(i)}Γ~d(i)={(j,d(j))∣j∈Γd(i)}\widetilde{\Gamma}_d(\mathbf{i}) = \{(\mathbf{j},d(\mathbf{j})) \mid \mathbf{j} \in \Gamma_d(\mathbf{i}) \}fffdddΓ˜dΓ~d\widetilde{\Gamma}_d 当限制的粒度粗糙区域(左侧,左上,上,右上,...当前单元格)的一个观察到有三个基本例(高达对称性和旋转)的有效动态编程递归,通知如何填充表:ΓdΓd\Gamma_d 红色区域表示(近似)。情况一和二承认子集,情况三是最坏的情况(直到索引转换)。注意,并非严格要求整个红色区域都被Γ覆盖;表格每个红色部分中的一些单元格足以将其涂成红色。明确要求白色区域不包含任何必需的单元格。ΓΓ\GammaΓΓ\Gamma 第一种情况的示例是编辑距离和最长公共子序列,第二种情况适用于Bellman&Ford和CYK。不太明显的例子包括:对角线而不是行(或列),因为它们可以旋转以适应所提出的情况;有关示例,请参见乔的答案。 不过,对于情况三,我没有(自然的)例子!所以我的问题是:案例三的动态编程递归/问题有哪些示例?

6
动态编程与蛮力编程有何不同
当我遇到以下引用时,我正在阅读动态编程 动态编程算法将研究解决问题的所有可能方法,并选择最佳解决方案。因此,我们可以将动态编程粗略地认为是一种智能的,蛮力的方法,它使我们能够通过所有可能的解决方案来选择最佳方案。如果问题的范围如此之大,以至于可以快速解决所有可能的解决方案,那么动态编程可确保找到最佳解决方案 给出了以下示例 例如,假设您必须在高峰时段在给定的城市中尽快从A点到达B点。动态规划算法将调查整个交通报告,调查您可能会走的所有可能的道路组合,然后才告诉您哪种方式最快。当然,您可能需要等待一段时间才能完成算法,然后才能开始驾驶。您将采用的路径将是最快的路径(假设外部环境没有任何变化) 蛮力在决定最佳解决方案之前,正在尝试所有可能的解决方案。 如果动态编程在选择最佳解决方案之前也要通过所有可能的解决方案,那么它与Brute Force 有何不同,我看到的唯一区别是动态编程考虑了其他因素(在这种情况下为交通状况)。 我正确地说动态编程是蛮力方法的子集吗?

3
可被n整除的最大和
我在StackOverflow上问了这个问题,但我认为这是一个更合适的地方。 这是算法概论课程中的一个问题: 您有aaa包含nnn正整数的数组a(该数组无需排序或元素唯一)。建议使用O(n)O(n)O(n)算法查找可被整除的元素的最大和nnn。 例如: a=[6,1,13,4,9,8,25],n=7a=[6,1,13,4,9,8,25],n=7a = [6, 1, 13, 4, 9, 8, 25], n = 7。答案是565656(与元件6,13,4,8,256,13,4,8,256, 13, 4, 8, 25) 这是比较容易找到它O(n2)O(n2)O(n^2)使用动态编程和存储与余最大的一笔0,1,2,...,n−10,1,2,...,n−10, 1, 2,..., n - 1。 另外,如果我们将注意力集中在元素的连续序列上,则可以通过存储部分和以n为模的总和来轻松地在O(n)O(n)O(n)时间内找到最佳的此类序列:让S [ i ] = a [ 0 ] + a [ 1 ] + ⋯ + 一个[ 我],对于每个剩余ř记住最大索引Ĵ使得小号[ Ĵ ] ≡ řnnnS[i]=a[0]+a[1]+⋯+a[i]S[i]=a[0]+a[1]+⋯+a[i]S[i]=a[0]+a[1]+\dots + …

3
切割字符串的动态编程练习
我一直在研究本书中的以下问题。 某种字符串处理语言提供了一种原始操作,该操作将字符串分成两部分。由于此操作涉及复制原始字符串,因此与剪切位置无关,长度为n的字符串要花费n个时间单位。现在,假设您要将一个字符串分成许多段。中断的顺序可能会影响总运行时间。例如,如果要在位置以切割20个字符的字符串和,然后在位置使第一切口即被的总成本,而这样做位置10首先具有更好的成本。10 3 20 + 17 = 37 20 + 10 = 3033310101033320+17=3720+17=3720 + 17 = 3720+10=3020+10=3020 + 10 = 30 我需要一种动态编程算法,该算法可给出剪切,以找到将字符串剪切成片段的最低成本。m + 1mmmm+1m+1m +1

3
没有数组的记忆
在Cormen等人的“算法简介”中,第15.3节动态编程的元素对记忆的解释如下: 记忆的递归算法为每个子问题的解决方案在表中维护一个条目。每个表条目最初都包含一个特殊值,以指示该条目尚未填写。当递归算法展开时,第一次遇到子问题时,将计算其解决方案,然后将其存储在表中。以后每次遇到此子问题时,我们只需查找表中存储的值并返回它。 并且添加了一个脚注: 这种方法的前提是我们知道所有可能的子问题参数的集合,并且已经建立了表位置和子问题之间的关系。另一种更通用的方法是通过使用以子问题参数作为键的哈希来记忆。 是否有任何众所周知的DP问题需要(或使其更容易)将已存储的值存储在字典中,而不是在(多维)数组中? 背景:如果有什么用,这个问题的原因是我正试图将(自平衡)二进制搜索树的概念激发给刚刚看过动态编程的人们。


2
矩阵链乘法和求幂
如果我有两个矩阵AAA和BBB,分别为维度1000×21000×21000\times2和2×10002×10002\times1000,并且要计算(AB)5000(AB)5000(AB)^{5000},则将表达式重写为A(BA)^ {4999}效率更高BA(BA)4999BA(BA)4999BA(BA)^{4999}B,然后才进行数字评估,因为ABABAB的尺寸为1000×10001000×10001000\times1000而BABABA的尺寸为2×22×22\times2。 我想解决此问题的广义版本。是否有合理有效的算法(不是蛮力)来优化包含以下内容的表达式: 已知尺寸的自由矩阵变量 任意子表达式的乘积 任意子表达式提升为自然幂 ...这样,用自由矩阵变量替换为具体的矩阵值之后,进行数字评估所需的工作最少。 该矩阵链乘积问题是我的问题的一个特例。 编辑: 这是一个暂定答案。直觉上对我来说似乎正确,但是我没有证据证明它是正确的。如果事实证明是正确的,我仍然对证明感兴趣。(当然,如果不正确,请纠正我。) 对于每个乘幂的乘积,例如(A_1 A_2 \ ldots A_k)^ n(A1A2…Ak)n(A1A2…Ak)n(A_1 A_2 \ldots A_k)^n,请考虑因子的每个循环排列: (A1A2…Ak)n(A1A2…Ak)n(A_1 A_2 \ldots A_k)^n A1(A2…AkA1)n−1A2…AkA1(A2…AkA1)n−1A2…AkA_1 (A_2 \ldots A_k A_1)^{n-1} A_2 \ldots A_k A1A2(A3…AkA1A2)n−1A3…AkA1A2(A3…AkA1A2)n−1A3…AkA_1 A_2 (A_3 \ldots A_k A_1 A_2)^{n-1} A_3 \ldots A_k ... A1A2…Ak−1(AkA1A2…Ak−1)n−1AkA1A2…Ak−1(AkA1A2…Ak−1)n−1AkA_1 A_2 \ldots A_{k-1} (A_k A_1 A_2 \ldots …

2
时间的词分解
给定两个字符串小号1个,S2S1,S2S_1, S_2,我们为它们的串联写小号1个小号2S1S2S_1S_2。如果给定字符串小号SS和整数ķ ≥ 1k≥1k\geq 1,我们写(S)ķ= S小号⋯ 小号(S)k=SS⋯S(S)^k = SS\cdots S为串接ķkk的副本小号SS。现在给定一个字符串,我们可以使用此符号“压缩”它,即A A B A A BAABAABAABAAB可以写为((A )2B )2((A)2B)2((A)^2 B)^2。让我们称之为a的重量压缩出现在它的字符数,所以的重量((A )2乙2)((A)2B2)((A)^2 B^2)是两个,并且重量(A B )2一个(AB)2A(AB)^2 A(一压缩的A B A B AABABAABABA)是三个(单独的AAA s分别计算)。 现在考虑用|计算给定字符串SSS的“最轻”压缩的问题。S | = n。经过一番思考,有一种明显的动态编程方法可以根据确切的方法在O (n 3 log n )或O (n 3)中运行。|S|=n|S|=n|S|=nO(n3logn)O(n3log⁡n)O(n^3 \log n)O(n3)O(n3)O(n^3) 但是,有人告诉我这个问题可以在O(n2logn)O(n2log⁡n)O(n^2 \log n)时间内解决,尽管我找不到有关如何执行此操作的任何资料。具体来说,这个问题是在最近的编程竞赛中给出的(问题K 在这里,最后两页)。在分析过程中,提出了O(n3logn)O(n3log⁡n)O(n^3 \log n)算法,最后提到了伪二次边界(此处为4分钟标记)。遗憾的是,主持人只提到了“一个复杂的单词组合引理”,所以现在我来这里寻求解决方案:-)

1
背包问题的变体
如果现在必须将背包中的项目数限制为常数那么在动态编程情况下如何解决背包问题?这是相同的问题(最大重量,每个商品的值均为,重量),但您只能将项添加到背包,显然需要优化背包的值。pppWWWvvvwwwppp 我们需要三维还是没有三维我们可以找到其他方法。我试图简单地在单元格中的背包中添加项目数,并在最后加上最大值,即项目数<=但这不是最佳解决方案。ppp

2
具有大量子问题的动态编程
具有大量子问题的动态编程。因此,我正在尝试通过Interview Street解决此问题: 网格漫游(得分50分) 您位于维网格中,位置为。网格的尺寸为)。一步,您可以在维度中的任何一个维度上向前或向后走一步。(因此,总是有可能的不同动作)。您可以采用多少种方法采取步骤,以使您在任何时候都不会离开网格?如果有任何,则离开网格,或。(X 1,X 2,... ,X Ñ)(d 1,d 2,... ,d Ñ Ñ 2 Ñ 中号X 我X 我 ≤ 0 X 我 > d 我NNN(x1,x2,…,xN)(x1,x2,…,xN)(x_1,x_2,\dots,x_N)(D1,D2,…,DN(D1,D2,…,DN(D_1,D_2,\dots,D_NNNN2N2N2NMMMxixix_ixi≤0xi≤0x_i \leq 0xi>Dixi>Dix_i > D_i 我的第一个尝试是这个记住的递归解决方案: def number_of_ways(steps, starting_point): global n, dimensions, mem #print steps, starting_point if (steps, tuple(starting_point)) in mem: return mem[(steps, tuple(starting_point))] val = …

1
难道这是一个NP完全问题?
考虑以下问题陈述: 给定一个初始数字,您和您的朋友轮流从中减去一个完美的平方。第一个获得零胜利的人。例如: 初始状态:37 玩家1减去16。状态:21 玩家2减去8。状态:13 玩家1减去4。状态:9 玩家2减去9。状态:0 Player2获胜! 编写一个程序,该程序给出一个初始状态,并返回最佳动作,即可以确保赢得比赛的动作。如果没有任何可能的举动会导致您进入获胜状态,请返回-1。 使用动态规划可以在伪多项式时间内解决此问题。这个想法只是用最佳移动从下往上填充长度为n(其中n是初始状态)的数组,如果没有移动导致获胜,则为-1。这将花费O(n * sqrt(n)),因为对于每个数字,我们都需要考虑减去每个可能的小于它的理想平方(其中有〜sqrt(n)个)。但是,这是伪多项式运行时复杂性,因为运行时实际上相对于二进制(用于表示数字的位数)的大小与输入大小成比例关系。 谁能想到解决这个问题的多项式算法?如果没有,那么它可以是NP-Complete吗?为什么?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.