维持秩序时两个有序列表中项目的最优配对策略算法

我有以下两个有序的项目列表:

A = ["apples","oranges","bananas","blueberries"]
B = ["apples","blueberries","oranges","bananas"]

每个项目的分数等于字符串的长度,所以……

apples = 6 points
oranges = 7 points
bananas = 7 points
blueberries = 11 points

我想创建一个对(A,B)列表,其中包含A的索引或B的索引或两者的索引,而不更改它们在每个列表中出现的顺序.

然后每一对都有其项目的分数,因此通过配对项目,我们将两个项目的总分减半.我想获得分数最小的对的组合.

例如,在上面的两个列表中,每个项目都可以配对,但有些配对会阻止我们配对其他配对,因为我们无法在不更改其中一个列表的顺序的情况下将两者配对.例如,我们不能将“蓝莓”配对,也可以配对“橙子”,因为“橙子”在一个列表中位于“蓝莓”之前,而在另一个列表中则位于“蓝莓”之后.我们只能配对一个或另一个.每个列表也可以多次具有相同的项目.

上述问题的最佳结果是……

    +---+---+----------------+-------+
    | A | B | Value          | Score |
+---+---+---+----------------+-------+
| 0 | 0 | 0 | "apples"       | 6     |
+---+---+---+----------------+-------+
| 1 | - | 1 | "blueberries"  | 11    |
+---+---+---+----------------+-------+
| 2 | 1 | 2 | "oranges"      | 7     |
+---+---+---+----------------+-------+
| 3 | 2 | 3 | "bananas"      | 7     |
+---+---+---+----------------+-------+
| 4 | 3 | - | "blueberries"  | 11    |
+---+---+---+--------+-------+-------+
                     | Total | 42    |
                     +-------+-------+

我认为答案是这样的:

>找到对
>将这些对分成可能的对组
>计算体重最大的组

通过将对从一个列表连接到另一个列表,我可以确定哪些对在视觉上排除了哪些对,如果该连接与另一个连接相交,则它将其排除.我不确定如何以编程方式完成此操作.

我怎么解决这个问题?

最佳答案 请注意,我的回答假设只有2个列表,并且每个列表中的项目最多只能有一次.

您要做的第一件事是构建一个地图/字典,其中项目作为键,一对整数作为值.此映射将包含两个数组中一个项的索引.运行第一个列表并将索引放在该对的第一个值中,并将第二个值放在-1中.对第二个列表执行相同操作但显然将索引放在第二个值中.像这样的东西:

pairs = map<string, pair<int, int>>

i = 0
while i < A.Length
    pairs[A[i]].first = i
    pairs[A[i]].second = -1
    i++
i = 0
while i < B.Length
    pairs[B[i]].second = i
    i++

现在,您必须确定可以执行的对组合.此伪代码创建所有可能组合的列表:

i = 0
while i < A.Length
    j = i
    index = -1
    combination = list<pair>
    while j < A.Length
        pair = pairs[A[j]]
        if pair.second > index
            combination.add(pair)
            index = pair.second
        j++
    combinations.add(combination)
    i++

现在,剩下的就是权衡可能的组合,但不要忘记包括未配对的项目.

编辑

我现在想的是为每个项目构建一个所有可能对的映射.会产生以下结果的东西.

oranges: [0,2][0,5][5,2][5,5][0,-1][-1,2][5,-1][-1,5]
apples: [1,1][1,-1][-1,1]
bananas: [2,3][2,-1][-1,3]
... 

使用排除逻辑,我们可以对这些对进行分组,并生成对列表列表的映射.

oranges: [0,2][5,-1][-1,5], [0,5][5,-1][-1,2], ..., [0,-1][5,-1][-1,2][-1,5]
apples: [1,1], [1,-1][-1,1]
...

现在,每个项目只能在结果输出中使用一个对的列表,而某些列表在不同的项目之间相互排斥.剩下的就是提出一种算法来权衡每种可能性.

点赞