我遇到过这个我无法解决的算法问题:https://prologin.org/train/2017/semifinal/collection_de_feuilles(法语)。
N
,K
和M[]
将作为输入。 N
指的是项目数量,M[i]
是第i堆中的项目数。如果j> 1,您只能将第i组M[i]
项合并到第j组M[j]
项中。 i,此合并的成本定义为M[i] * (j - i)
。输出是将初始N
桩合并为K
桩的最低成本。
我的想法是使用函数min_rearrange(x, num_piles)
来计算将M[x]
到M[N - 1]
的堆重新排列成指定数量的桩的最低成本。当num_piles
等于1时,此函数返回将M[j]
移动到M[N -
1]
的成本之和,x≤j<1。 N.否则,因为必须存在i
,其中x≤i≤N - num_piles,我们将所有桩从M[x]
移动到M[i - 1]
到M[i]
,我们计算出求和,然后递归调用min_rearrange(i + 1, num_piles - 1)
以找到最低成本。
我也试图记住解决方案:
# https://prologin.org/train/2017/semifinal/collection_de_feuilles
n, k = map(int, input().split())
piles = list(map(int, input().split()))
memory = {}
def min_rearrange(x, num_piles):
"""Min cost to rearrange piles[x:] into num_piles"""
if (x, num_piles) in memory:
return memory[x, num_piles]
if num_piles == 1:
memory[x, num_piles] = sum([(n - 1 - i) * piles[i] for i in range(x, n)])
return memory[x, num_piles]
min_cost = float('inf')
for i in range(x, n - num_piles + 1):
cost = sum([(i - j) * piles[j] for j in range(x, i)])
min_cost = min(min_cost, cost + min_rearrange(i + 1, num_piles - 1))
memory[x, num_piles] = min_cost
return min_cost
print(min_rearrange(0, k))
但是大输入尺寸需要花费太多时间。我想知道如何更有效地解决问题。