【问题标题】:How to implement Dynamic Programming in the following recusrion?如何在下面的递归中实现动态规划?
【发布时间】:2012-10-07 13:40:55
【问题描述】:

我有以下递归:

if(a%2 == 0){
f([a1,a2,...,aN],a,N) = (a1 + aN)/2 + f([a1,a2,...,a(N-1)],a+1,N-1)/2 + 
f([a2,...,aN],a+1,N-1)/2;
}
else{
f([a1,a2,...,aN],a,N) = f([a1,a2,...,a(N-1)],a+1,N-1)/2 + 
f([a2,...,aN],a+1,N-1)/2;
}

基本情况:

f([a1,a2],a,2) = (a1+a2)/2;

显然,如果我递归地实现它,就会出现堆栈溢出。我应该如何利用动态规划来获得这个递归的最优解?

[a1,a2,..,aN] 表示一个整数数组。

N 的限制是 2000 和 a1,a2,..,aN

【问题讨论】:

  • 为什么会出现堆栈溢出?
  • 我试过了,一直报运行时错误...:(

标签: c algorithm recursion


【解决方案1】:

这闻起来很像家庭作业问题。我建议您与讲师或助教见面,因为这是最好的互动学习方式。如果您使用此信息,请务必引用,以免抄袭。

首先,观察结果在值[a0, a1, ... aN] 中是线性的。因此,您实际上只需要跟踪它们的系数。出于符号的目的,让我们写{b1, b2, ..., bN} 来代表b1 * a1 + b2 * a2 + ... bN * aN

接下来,手工算出一些递归:

f([a1, a2], a, 2) = { 1/2, 1/2 }N=2 的基本情况。

我们来看看N=3

f([a1, a2, a3], a, 3)a 甚至 = {1/2, 0, 1/2} + { f([a1, a2], a+1, 2)/2, 0 } + { 0, f([a2, a3], a+1, 2)/2 } = { 1/2, 0, 1/2 } + { 1/4, 1/4, 0 } + { 0, 1/4, 1/4 } = { 3/4, 1/2, 3/4 }

f([a1, a2, a3], a, 3)a 奇数 = { f([a1, a2], a+1, 2)/2, 0 } + { 0, f([a2, a3], a+1, 2)/2 } = { 1/2, 0, 1/2 } + { 1/4, 1/4, 0 } + { 0, 1/4, 1/4 } = { 1/4, 1/2, 1/4 }

现在N=4:

f([a1, a2, a3, a4], a, 4)a 甚至 = { 1/2, 0, 0, 1/2 } + { f[a1, a2, a3], a+1, 3)/2, 0 } + { 0, f([a2, a3, a4], a+1, 3)/2 }。因为a 是偶数,a+1 是奇数,所以我们是F([], even, 3)f([a1, a2, a3, a4], a, 4)a 甚至 = { 1/2, 0, 0, 1/2 } + { 1/8, 1/4, 1/8, 0 } + { 0, 1/8, 1/4, 1/8 } = { 5/8, 3/8, 3/8, 5/8 }

f([a1, a2, a3, a4], a, 4)a 奇数 = { f[a1, a2, a3], even, 3)/2, 0 } + { 0, f([a2, a3, a4], even, 3)/2 } = { 3/8, 1/4, 3/8, 0 } + { 0, 3/8, 1/4, 3/8 } = { 3/8, 5/8, 5/8, 3/8 }

现在您可以看到系数仅取决于 N 以及 a 是偶数还是奇数。

这意味着您的动态规划只需要记住N 和布尔值的每个组合的系数。由于N 的上限为 2000,这意味着您只需要 4000 个条目,这不应该是太大的负担。事实上,您可以放弃递归,像我们上面所做的那样简单地增量计算整个表。

【讨论】:

  • 我完全遵循了递归,我没有遵循的是“观察到的”初始数组人口。我在他的描述中看不到任何关于 [a1,a2,...] 人口的内容,当然,无论如何,它是恒定的,并且仅在奇数情况下为下一次递归调整根索引。此外,给定一个值为 [1,1] 的数组 A[],不是基本情况,那么 fn() = (1+1)/2 = 1?在您的笔记中,您将其命名为 {1/2,1/2} ?还是我完全阅读了他(和你)使用不正确的符号?不要杀死宗教裁判所。自从我做递归系数以来已经很久了。谢谢。
  • 如第二段所述,符号{1/2, 1/2} 表示(1/2)*a1 + (1/2)*a2
  • 罗杰。我正在寻找他们在 his 基本定义中定义的总和。谢谢。
  • @Raymond Chen:非常好的推理。我的解决方案被接受了:)
  • @jigsawmnc 你记得要感谢设计解决方案的人吗? (你所说的“接受”是什么意思?导师会不会怀疑原来无法进行动态编程的人突然对递归关系提出了多种优化见解?)
【解决方案2】:

您需要存储所有 a,N 值对的答案

【讨论】:

    【解决方案3】:

    可以以增量方式计算每个 ai 的系数。我相信给定 n 的一半系数需要计算,因为另一半将包含重复的元素。所以每个 n 将在表中包含 n/2 个值。这种方法将导致 n^2 运行时间。不知道这是否可以进一步改进。

    【讨论】:

    • @jigsawmnc 这是实现的样子还是可以进一步改进?
    猜你喜欢
    • 2013-11-14
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 2012-07-10
    • 2011-11-09
    • 1970-01-01
    • 2020-11-20
    相关资源
    最近更新 更多