我有一张关于A队和B队的表格,其中每对2名球员之间都有一个数字。行代表A队的球员,列代表B队的球员。如果一个数字为正数,意味着A队的球员比B队的球员好,如果是负数则相反。
例如:
-710 415 527 -641 175 48
-447 -799 253 626 304 895
509 -523 -758 -678 -689 92
24 -318 -61 -9 174 255
487 408 696 861 -394 -67
两支队伍都了解这张表格。现在,团队A报告了5名球员,团队B可以查看并选择最适合他们的5名球员。如果我们想比较球队,我们总结从表格中给定的位置上的数字,知道每个队都有一个被计算两次的队长(就像一个队有6个球员且队长出现两次),如果总和是正数,则团队A更好。
输入的数字为a
(行/球员数A)和b
(列/球员数B),表格如下:
6
6
-54 -927 428 -510 911 93
-710 415 527 -641 175 48
-447 -799 253 626 304 895
509 -523 -758 -678 -689 92
24 -318 -61 -9 174 255
487 408 696 861 -394 -67
输出应该是1282。
所以,我所做的是将数字放入一个矩阵中,就像这样:
a, b = int(input()), int(input())
matrix = [list(map(int,input().split())) for _ in range(a)]
我在这里使用了一个最小堆和一个最大堆。我将行放入最大堆中,因为A队想要最大的,然后我从中获取5个最好的A球员,如下所示:
for player, values in enumerate(matrix):
maxheap.enqueue(sum(values), player)
playersA = []
overallA = 0
for i in range(5):
ov, pl = maxheap.remove_max()
if i == 0: # it is a captain
playersA.append(pl)
overallA += ov
playersA.append(pl)
overallA += ov
B 队知道 A 球队的使用情况,他们使用 MinHeap 来找到自己最好的 5 名球员:
for i in range(b):
player = []
ov = 0
for j in range(a): #take out a column of a matrix
player.append(matrix[j][i])
for rival in playersA: #counting only players already chosen by A
ov += player[rival]
minheap.enqueue(ov,i)
playersB = []
overallB = 0
for i in range(5):
ov, pl = minheap.remove_min()
if i == 0:
playersB.append(pl)
overallB += ov
playersB.append(pl)
overallB += ov
给定玩家后,我从矩阵中计算总和:
out = 0
for a in playersA:
for b in playersB:
out += matrix[a][b]
print(out)
然而,这种解决方案并不能总是给出正确的结果。例如,对于以下输入,它并不能返回正确的结果:
10
10
-802 -781 826 997 -403 243 -533 -694 195 182
103 182 -14 130 953 -900 43 334 -724 716
-350 506 184 691 -785 742 -303 -682 186 -520
25 -815 475 -407 -78 509 -512 714 898 243
758 -743 -504 -160 855 -792 -177 747 188 -190
333 -439 529 795 -500 112 625 -2 -994 282
824 498 -899 158 453 644 117 598 432 310
-799 594 933 -15 47 -687 68 480 -933 -631
741 400 979 -52 -78 -744 -573 -170 882 -610
-376 -928 -324 658 -538 811 -724 848 344 -308
但它并不适用于
11
11
279 475 -894 -641 -716 687 253 -451 580 -727 -509
880 -778 -867 -527 816 -458 -136 -517 217 58 740
360 -841 492 -3 940 754 -584 715 -389 438 -887
-739 664 972 838 -974 -802 799 258 628 3 815
952 -404 -273 -323 -948 674 687 233 62 -339 352
285 -535 -812 -452 -335 -452 -799 -902 691 195 -837
-78 56 459 -178 631 -348 481 608 -131 -575 732
-212 -826 -547 440 -399 -994 486 -382 -509 483 -786
-94 -983 785 -8 445 -462 -138 804 749 890 -890
-184 872 -341 776 447 -573 405 462 -76 -69 906
-617 704 292 287 464 -711 354 428 444 -42 45
所以问题是:是否可以这样做,或者是否存在另一个快速算法(O(n ** 2) / O(n ** 3)等),或者我只能使用O(n!)的暴力方法尝试所有可能的组合?