" 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
答案 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的唯一方法。如果是,请更新数据结构以记录此答案。
当你完成所有位置后,寻找最便宜的方式来覆盖所有位置,看看最后使用的炸弹是什么。然后看看炸弹留下的最右边的索引,看看最便宜的方法至少覆盖到找到下一个要使用的炸弹 - 等等。