在记忆方面的状态似乎与自开始以来经过的时间无关。采取任何起始位置,
a, b, c
其中a, b, c 是选定的幅度(每个歌手可以屏住呼吸的时间),a 是最小的幅度。我们有
a, b, c
t = 0
和它一样:
0, b - a, c - a
t = a
所以让我们定义具有最小幅度的初始状态a 为:
b, c, ba, ca
where ba = b - a
ca = c - a
t = a
从这里开始,状态的每一次转换都是相似的:
new_a <- x
where x is a magnitude in
the list that can be available
together with b and c. (We only
need to try each such unique
magnitude once during this
iteration. We must also prevent
a singer from repeating.)
let m = min(new_a, ba, ca)
then the new state is:
u, v, um, vm
t = t + m
where u and v are from the
elements of [new_a, b, c] that
aren't associated with m, and um
and vm are their pairs from
[new_a, ba, ca] that aren't m,
subtracted by m.
已访问组合的记忆状态只能是:
[(b, ba), (c, ca)] sorted by
the tuples' first element
如果到达的关联t 等于或高于该状态下看到的最小值,我们可以使用它修剪搜索中的分支。
例子:
2 4 7 6 5
解决方案(自上而下阅读):
4 5 6
7 4 5
2
州:
u v um vm
5 6 1 2
t = 4
new_a = 7
m = min(7, 1, 2) = 1 (associated with 5)
7 6 6 1
t = 5
new_a = 4
m = min(4, 6, 1) = 1 (associated with 6)
4 7 3 5
t = 6
new_a = 5
m = min(5, 3, 5) = 3 (associated with 4)
5 7 2 2
t = 9
new_a = 2
m = min(2, 2, 2) = 2 (associated with 2)
5 7 0 0
t = 11
Python 代码:
import heapq
from itertools import combinations
def f(A):
mag_counts = {}
for x in A:
if x in mag_counts:
mag_counts[x] = mag_counts[x] + 1
else:
mag_counts[x] = 1
q = []
seen = set()
# Initialise the queue with unique starting combinations
for comb in combinations(A, 3):
sorted_comb = tuple(sorted(comb))
if not sorted_comb in seen:
(a, b, c) = sorted_comb
heapq.heappush(q, (a, (b-a, b), (c-a, c), a))
seen.add(sorted_comb)
while q:
(t, (ba, b), (ca, c), prev) = heapq.heappop(q)
if ba == 0 and ca == 0:
return t
for mag in mag_counts.keys():
# Check that the magnitude is available
# and the same singer is not repeating.
[three, two] = [3, 2] if mag != prev else [4, 3]
if mag == b == c and mag_counts[mag] < three:
continue
elif mag == b and mag_counts[mag] < two:
continue
elif mag == c and mag_counts[mag] < two:
continue
elif mag == prev and mag_counts[mag] < 2:
continue
m = min(mag, ba, ca)
if m == mag:
heapq.heappush(q, (t + m, (ba-m, b), (ca-m, c), m))
elif m == ba:
heapq.heappush(q, (t + m, (mag-m, mag), (ca-m, c), b))
else:
heapq.heappush(q, (t + m, (mag-m, mag), (ba-m, b), c))
return float('inf')
As = [
[3, 2, 3, 3], # 3
[1, 2, 3, 2, 4], # 3
[2, 4, 7, 6, 5] # 11
]
for A in As:
print A, f(A)