动态编程 - 制作建筑物的方法数量

时间:2015-10-16 06:19:04

标签: algorithm dynamic-programming

我试图使用动态编程来解决以下类型的问题 - 我似乎无法找到重现。问题如下:

“建筑物是由至少两个街区组成的结构。

您的任务是找到总体方式,以便在建造建筑物时使用所有街区。

例如,对于n = 5,答案是2,因为[5],[2,3]。

对于n = 6,答案是4,因为[6],[2,4],[2,2,2],[3,3]“

有人可以帮我理解如何从下到上或从上到下的方式做到这一点?

2 个答案:

答案 0 :(得分:0)

这与partition problem的想法相同。让f[i][j]在非递减大小的块中减去i的分区数,使最后一个块大小为j。那么,您的更新规则是:

f[i+k][k] += f[i][j], for k>= max(2, j) // bottom-up approach

以及分区数量的答案:

f[n][2] + f[n][3] + ... + f[n][n]

或者,您可以使用自上而下的方法:

f[i][j] += f[i-k][k] for 2 <= k <= j

在您的示例上运行此操作:

Initialize f[i][i] = 1, i >= 2 and the rest set to 0

f[2][2] = 1

f[3][2] = f[1][2] = 0
f[3][3] = 1

f[4][2] = f[2][2] = 1
f[4][3] = f[1][2] + f[1][3] = 0
f[4][4] = 1

f[5][2] = f[3][2] = 0
f[5][3] = f[2][2] + f[2][3] = 1
f[5][4] = f[1][2] + f[1][3] + f[1][4] = 0
f[5][5] = 1


f[6][2] = f[4][2] = 1
f[6][3] = f[3][2] + f[3][3] = 1
f[6][4] = f[2][2] + f[2][3] + f[2][4] = 1
f[6][5] = f[1][2] + f[1][3] + f[1][4] + f[1][5] = 0
f[6][6] = 1

count(5) = f[5][2] + f[5][3] + f[5][4] + f[5][5] = 2
count(6) = f[6][2] + f[6][3] + f[6][4] + f[6][5] + f[6][6] = 4

答案 1 :(得分:0)

实际上有一个非常简单的解决方案:包含n的{​​{1}}分区数等于1的分区总数。想到它的一种方法是想象从(n - 1)的每个包含一个1的分区中删除一个n;任何不包含n的{​​{1}}分区都无法以这种方式进行转换。

因此,我们只需从经典partition recurrence1中删除第一个字词,然后派生:

p(k) = p(k − 1) + p(k − 2) − p(k − 5) − p(k − 7) + p(k − 12) + p(k − 15) − p(k − 22) − ...

或者

p_without_1s(k) = p(k − 2) − p(k − 5) − p(k − 7) + p(k − 12) + p(k − 15) − p(k − 22) − ...