1 条题解
-
0
XzyStudio (admin) LV 8 MOD RP++ tayz @ 7 个月前
一个重要的观察是,我们永远不会移动同一个元素两次, 因此最终的解就是移动元素的最小数量 。
另一个关键点是,我们实际上不需要逐个执行操作。可以假设我们首先将一些元素取出,然后将它们插入到我们选择的某个位置。
对于一些特殊情况,如果数组中至少包含一个 0 和一个 1,但没有 2,则无法找到有效解。如果数组中至少有一个 2,我们可以将所有 0 移到数组的左侧,将所有 1 移到右侧。若数组仅包含 0 或仅包含 1,那么不需要任何移动,答案为 0。
在我们的解决方案中,我们假设至少有一个 0 和一个 1 不被移动。因此,当最优选择是移动所有的 0(或者所有的 1,这两种情况类似)时,需要处理一些特殊情况。如果我们移动所有的 0,可以将它们插入到两个 2 之间(如果存在这样的两个 2)。否则,我们需要执行一次额外的移动:取出一个 2,将其移到数组的末尾,然后将所有 0 放在后面。如果数组的第一个(或最后一个)元素已经是 2,则无需进行额外的移动。
一般情况下,我们假设至少有一个 0 和一个 1 不被移动。我们选择删除部分 0、部分 1 以及部分 2。左边的数组(最终状态)可能会存在一些相邻的冲突元素对。删除的 2 的数量需要等于或多于这些冲突的数量。在这种情况下,我们可以找到一个有效的解决方案,因为可以将所有的 0 插入到未移动的某个 0 的旁边(对 1 也执行相同的操作)。
我们的方法是先移除所有的 2,并在它们的位置留下空白。因此,初始成本等于数组中 2 的总数。接下来,从左到右遍历数组。当遇到 0 或 1 时,我们可以选择删除或保留它们。如果保留,我们可能需要在其前面插入一个 2 来解决潜在的冲突。当到达空白位置时,可以选择不进行操作并继续,或者插入一个 2。后者的选择会使成本减少 1,就像一开始没有移动该元素一样。
动态规划的解决方案开始成型:
设
表示处理长度为 的前缀时的最小成本,其中: 是我们插入的 2 的数量; 是前缀最后一个元素的值; 是一个二进制掩码,两位分别表示是否至少有一个 0 和一个 1 未被移动。
最终解可以通过检查
来获得。递归的计算时间为 ,因此时间复杂度为 。注意到对于某个长度
的所有值,仅依赖于 的值,所以滚掉一维,可以将内存优化为 。
- 1
信息
- ID
- 1091
- 难度
- 9
- 分类
- (无)
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 通过率
- 100%
- 上传者