在采访中被问到:动态编程

时间:2013-11-16 17:37:32

标签: c arrays algorithm dynamic-programming

" N"炸弹被排成一排。每个炸弹都有一个"索引"对应它。说第i个位置炸弹的索引为k。这意味着当第i个炸弹扩散时,它会随着k炸弹向左扩散,而右边的k炸弹也会扩散。第一行输入包含数量N(炸弹数量),下一行包含空间分离炸弹指数(k)。打印输出作为此类炸弹的最小数量,当扩散时扩散所有其他炸弹,然后是炸弹指数。如果索引的组合不止一个,请在不同的行上打印。

例如

输入:

8

1 2 7 3 4 9 3 4

输出

1

9

输入:

20

1 1 1 9 1 1 1 1 1 4 1 1 1 1 1 8 1 1 1

输出

2

9 8

2 个答案:

答案 0 :(得分:1)

让:

dp[i] = minimum number of bombs that need to be defused in order to defuse
        all bombs in [1, i] considering only bombs in [1, i]

我们有:

dp[anything<=0] = 0
dp[1] = 1 <- must defuse the first bomb
dp[k] = min{dp[k - a[k]] + overlap, <- if the current bomb also defuses
                                       a[k] to its left and right, then we can just 
                                       defuse that and reduce the problem 
                                       to defusing bombs [1, k - a[k]]
            dp[k - a[k] + 1] + overlap, <- same reasoning; some overlaps might provide
                                           a better solution
            dp[k - a[k] + 2] + overlap,
            ...
            dp[k - 1] + overlap}

overlap 1 p = k - a[k] + i k 0炸弹dp[n]炸弹O(n^2) a = 1 2 7 3 4 9 3 4 dp[1] = 1 dp[2] = min{dp[2 - 2] + 1, dp[2 - 1] + 0 (because the first bomb also defuses this one} = 1 dp[3] = min{dp[3 - 7] + 1, dp[3 - 2] + 1 (because the first bomb does not also defuse this one), dp[3 - 1] + 0} = 1 ... 炸弹{{1}} {{1}}

答案为{{1}}。直接实施是{{1}}。有可能使这个线性化。

工作示例:

{{1}}

答案 1 :(得分:0)

似乎有无穷无尽的动态编程问题,其中有一些东西排成一行,您可以通过从左到右的工作来解决它们,使用先前计算的每个步骤的部分解决方案。

在这里,你可以考虑跟踪一个排序数组,它为你提供了覆盖第一个i位置的最低成本方式 - 这个成本是什么,最合适的炸弹在序列中达到了这个成本。随着我的增加,最低成本将增加,因为如果有更便宜的方式来覆盖n> m个位置而不是m个位置,你可以使用该解决方案覆盖m个位置并丢弃m个位置的答案。我说一个排序的数组,但标准的树/ SortedMap可能会更好。

在第i阶段,您需要花费至少i-1位置的所有费用来查看那里的索引k并将其与覆盖第一个ik位置的最佳方式相结合,看看这是否会让您更便宜(或覆盖第一个i + k的唯一方法。如果是,请更新数据结构以记录此答案。

当你完成所有位置后,寻找最便宜的方式来覆盖所有位置,看看最后使用的炸弹是什么。然后看看炸弹留下的最右边的索引,看看最便宜的方法至少覆盖到找到下一个要使用的炸弹 - 等等。