我们给出方数矩阵,例如
1 9 2
3 8 3
2 1 1
相邻数字之间的距离为2
。我们希望在同一行或同一列中找到这样的两个数字,它们的总和加上它们之间的距离是最大的。例如,在上面的示例中,此类数字为9
和8
,最大结果为9+8+1*2 = 19
。我们想要找到最大结果,我们不需要具体的数字。
对我来说这看起来像是一个DP问题,但我想不出任何优雅的解决方案。
答案 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算法,并返回找到的最大对。总的来说n
乘def 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