动态编程。硬币行问题-如何建立其递归关系

时间:2018-11-25 16:57:38

标签: dynamic-programming

问题:一组n个硬币连续放置。硬币具有正值,不必区分。在没有两个相邻硬币都不能拾取的约束条件下,找到可以收集的最大数量。

它的递归关系是

F(n) = max{cn + F(n − 2), F(n − 1)} for n > 1,
F(0) = 0, F(1) = c1.

我的问题是这种递归关系是如何发展的。请有人给我解释一下。

3 个答案:

答案 0 :(得分:4)

首先,设想一行硬币,每个硬币的值由变量ci表示:

c1 c2 c3 c4 c5 ... cn

如果没有硬币,显然可以制造的最大数量为0。同样,如果只有1个硬币,则最大数量为该硬币的价值c1。这就是基本情况。

对于 n 个硬币的最大值的递归情况,请从最右边的硬币cn开始。由于限制是您不能选择相邻的硬币,因此可以实现的最大值是最右边的一个硬币 加上从左侧2个插槽获得的最大值(这占f(n- 2),通过立即选择左侧的硬币(占f(n-1)情况)并丢弃最右边的硬币cn获得的最大值。

再次考虑以下几行硬币:

 c1 c2 c3 c4 c5 c6

f(6)的情况为c6 +硬币c1-c4中的最大金额,或硬币c1-c5中的最大金额(不包括c6)。

同样,

f(4)从硬币c1-c2返回c4 +最大值,或者从硬币c1-c3返回最大值(同样不包括c4)。

f(2)从c1返回c2 + c0或最大值(有效地为c1)第一个等于c2,因为在基本情况下c0为0,第二个等于c1(再次在基本情况下)。所以f(2)实际上只是c1或c2的最大值。

也请注意,f(n-2)和f(n-1) 可能相同,因为在n-1情况下,选择硬币左边(这是f(n-2)的情况)。但这就是为什么上半部不仅是f(n-2),而且还加上了cn

的原因。

答案 1 :(得分:1)

让我们从结尾开始。 让我们以Could not find platform independent libraries <prefix> Could not find platform dependent libraries <exec_prefix> Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>] Fatal Python error: Py_Initialize: unable to load the file system codec ModuleNotFoundError: No module named 'encodings' Current thread 0x000000011179c5c0 (most recent call first): Abort trap: 6

表示n个硬币的问题的答案

如果您有零个硬币,则金额为零。所以F(n)。 如果您只有一个硬币,则金额就是该硬币的价值,因此F(0) = 0

现在假设有人告诉您F(1)=c1的值。您如何使用它们来找到F(n-1), F(n-2)

如果您有n个硬币,则有两种可能的移动方式:

  1. 选择第n个硬币,跳过相邻的第一个((n-1)个硬币,这就是规则!),然后从那里继续求解。
  2. 跳过第n个硬币,然后从相邻的第(n-1)个位置恢复求解。

如何使用现有工具表达1和2的概念?

  1. 如果您选择第n个硬币,则其值为F(n)。现在您必须跳过第(n-1)个硬币,并继续从(n-2)个硬币求解。这是Cn
  2. 如果跳过第n个硬币,则其对解决方案的贡献为0,现在您从第(n-1)个硬币恢复求解。那是F(n-1)。

情况1或情况2中的哪个较大?你不知道但您可以将其表示为

Cn + F(n-2)

这是在说:“我不知道哪一个更大,但是请其中一个返回它。”

我希望这会有所帮助!

答案 2 :(得分:1)

让F(n)是可以从n个硬币行中提取的最大金额。

要得出F(n)的重复发生,我们将所有允许的硬币选择划分为两组:

包括最后一个硬币的硬币和没有最后一个硬币的硬币。

我们从第一组中获得的最大金额等于cn + F(n − 2)- 第n个硬币的价值加上我们从前n − 2个硬币中可以提取的最大金额。

根据F(n)的定义,我们从第二组中获得的最大金额等于F(n − 1)。