最大化两个数字之和加上它们之间的距离

时间:2018-04-03 10:26:37

标签: algorithm dynamic-programming

我们给出方数矩阵,例如

1 9 2
3 8 3
2 1 1

相邻数字之间的距离为2。我们希望在同一行或同一列中找到这样的两个数字,它们的总和加上它们之间的距离是最大的。例如,在上面的示例中,此类数字为98,最大结果为9+8+1*2 = 19。我们想要找到最大结果,我们不需要具体的数字。

对我来说这看起来像是一个DP问题,但我想不出任何优雅的解决方案。

1 个答案:

答案 0 :(得分:7)

可以使用动态编程解决1D问题(即,给定数字列表,找到最大化和+距离的对)。

bi = 0
best = -10**9  # anything large and negative
for i in range(1, n+1):
   best = max(best, a[i] + a[bi] + (i - bi)*2)
   if a[i] - i*2 > a[bi] - bi*2:
      bi = i

此代码完成后,best将存储列表中任何数字对的最大总和+距离。它的工作原理是因为在i的任何给定循环迭代中,bi存储索引值小于i的索引,该值最大化其值减去其索引的两倍。可以观察到该索引处的数字是i左边的最佳数字(i的左侧),用于将n处的数字与。{/ p>配对。

一旦你有了这个,2D问题很简单:遍历每一行和每一行并应用1D算法,并返回找到的最大对。总的来说ndef max_sum_dist_1D(a): bi = 0 best = -10**9 for i in range(1, len(a)): best = max(best, a[i] + a[bi] + (i - bi)*2) if a[i] - i*2 > a[bi] - bi*2: bi = i return best def max_sum_dist_2D(M): best_row = max(max_sum_dist_1D(row) for row in M) best_col = max(max_sum_dist_1D(col) for col in zip(*M)) return max(best_row, best_col) M = [[1, 9, 2], [3, 8, 3], [2, 1, 1]] print(max_sum_dist_2D(M)) 矩阵,这在O(n ^ 2)时间内运行,这显然是渐近最优的,因为矩阵中的每个元素都需要至少读取一次。

这是Python3的代码:

Sub DataSpreader()
    Dim s1 As Worksheet, s2 As Worksheet
    Dim i As Long, K As Long, j As Long
    Dim r As Range

    Set s1 = Sheets("Sheet1")
    Set s2 = Sheets("Sheet2")
    s2.Cells(1, 1) = s1.Cells(1, 1)
    K = 1

    For i = 2 To Intersect(Selection, s1.UsedRange).Count
            If s1.Cells(i, 1) = s1.Cells(i - 1, 1) Then
                s2.Cells(i, K + 1) = s1.Cells(i, 1)
                K = K + 1
            Else
                K = 1
                s2.Cells(i, 1) = s1.Cells(i, 1)
            End If
    Next i
End Sub