项链劈开问题
背景 我受到3Blue1Brown最近关于项链劈裂问题(或他所说的是被盗的项链问题)及其与Borsuk-Ulam定理的关系的视频的启发。 在这个问题上,两个小偷偷走了一条有价值的项链,该项链由几种不同类型的珠宝组成。每种珠宝的数量都是偶数,盗贼希望在两种珠宝中平均分配每种珠宝。要注意的是,他们必须这样做,方法是将项链分成若干个连续的片段,并将片段分配在两个片段之间。 这里是表示4种宝石类型的示例S,E,D,和R(对于蓝宝石,祖母绿,金刚石和红宝石,分别地)。假设项链如下: [S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E] 有8蓝宝石,10祖母绿,4钻石和6红宝石。我们可以如下分割项链: [[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]] 然后,如果我们将第一,第三和第五部分分配给一个小偷,而将第二和第四部分分配给另一个小偷,则每一个都会以4蓝宝石,5祖母绿,2钻石和3红宝石: [S], [S,E,S,D,E,R,S], [R,R,D,E,E,E] [S], [R,E,S,S,S,D,R,E,E,R,E,D,E], 使用 0 -indexing,这些削减发生在index处[1,2,9,22]。 目标 事实证明,这样的公平划分总是可以使用最多 n切割,这n是珠宝类型的数量。您的任务是编写一个完整的程序或函数,该程序或函数将一条项链作为输入,并输出最小的此类分割(最少的切割次数)。 输入项 输入可以采用任何方便的格式。项链应该是一系列珠宝,仅此而已;例如整数列表,字典,字典中的键代表珠宝类型,而值代表索引列表。您可以选择包括项链的长度或不同珠宝类型的数量,但您不应输入任何其他信息。 您可以假设输入的项链有效。您无需处理给定类型的珠宝数量奇数或项链为空的情况。 输出量 同样,输出可以采用任何方便的格式。例如,片段列表,切割位置列表,带有表示两个小偷的键的字典以及片段列表的值等。片段可以通过其起始索引,结束索引,连续索引列表,珠宝列表,它们的长度等。您可以使用0-或1-索引。如果顺序对您的格式不重要,则您的输出可以按任何顺序排列。以下是上述输出的几种不同格式: list of segments: [[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]] list of cuts: [1,2,9,22] list of lengths: [1,1,7,13,6] dictionary: {'thief1' : [(R,R,D,E,E,E),(S),(S,E,S,D,E,R,S)], 'thief2' : [(S),(R,E,S,S,S,D,R,E,E,R,E,D,E)]} 请注意,顺序在片段列表(小偷之间的片段交替)和长度列表(以识别片段)中很重要,但在剪切片段或字典中则不重要。 编辑:格雷格·马丁(Greg Martin)指出,这些将不是有效的输出,因为可以通过两次削减获得公平的划分 测试用例 [1,2,1,2,1,3,1,3,3,2,2,3] -> [[1,2,1],[2,1,3,1],[3,3,2],[2,3]] …