有一组大小N
S = {n1, n2, n3, ..., nN}
我需要在
M上拆分集合
S
Groups = {{n1, n2}, {n3, n4, n5...},...,{... nN}} -> len(Groups) = M
两个相邻组之间的最大差值应尽可能小。差额的计算方法如下:
diff = abs(sum(G1) - sum(G2)) = abs((n1 + n2) - (n3 + n4 + n5))
我可以生成所有大小为
N
的向量,其中只包含M
非零位数(如1
),但我将不得不考虑50! / (25! * 25!)
为错误的蛮力:(
例子:
6, 13, 10, 2
case 1: {6}, {13, 10, 2} -> difference = 25
case 2: {6, 13}, {10, 2} -> difference = 5
case 3: {6, 13, 10}, {2} -> difference = 29
The best case is second -> difference = 5!
我可以用什么方法来解决这个问题?
我通过结合动态规划和修改a*搜索解决了这个问题。
import heapq
def best_division (numbers, pieces):
cumulative_sums = [0]
for number in numbers:
cumulative_sums.append(cumulative_sums[-1] + number)
# We need this to be somewhat bigger than the maximum sum.
# Making it + pieces/2 will result in a better
# expected_piece_size.
sum_bound = cumulative_sums[-1] + (pieces // 2)
# We expect our pieces to be somewhere close to this size.
expected_piece_size = (cumulative_sums[-1] + (pieces//2)) // pieces
# This data structure will include:
#
# By completed segments
# By start of segment
# By end of segment
# (lowest maximum difference, prev_start)
#
# It will actually be an array of dictionaries of dictionaries.
#
# It starts off empty.
best_path_info = []
# The queue is a minimum priority queue.
#
# [
# lowest maximum difference,
# abs(sum of segment - expected_piece_size),
# count_pieces,
# start,
# end,
# prev_start
# ]
#
# This causes us to first look at the lowest maximum difference,
# and then at the segment sum being close to the expected.
#
# It also means we can trace backwards once we have an answer.
queue = []
for i in range(len(cumulative_sums)):
heapq.heappush(
queue, [
0,
abs(cumulative_sums[i] - expected_piece_size),
0,
0,
i,
None
])
while len(queue):
max_diff, _, count_completed, start, end, prev_start = heapq.heappop(queue)
if count_completed + 1 == pieces: # The current piece is not in the count
if end == len(numbers):
answer = [numbers[start:end]]
end = start
start = prev_start
while start is not None:
answer.append(numbers[start:end])
count_completed -= 1
prev_start = best_path_info[count_completed][start][end][1]
end = start
start = prev_start
### RETURN HERE ###
return list(reversed(answer))
else:
continue # Not a solution
if len(best_path_info) <= count_completed:
best_path_info.append({})
path = best_path_info[count_completed]
if start not in path:
path[start] = {}
path = path[start]
if end not in path or max_diff < path[end][0]:
path[end] = (max_diff, prev_start)
for next_end in range(end, len(cumulative_sums)):
this_sum = cumulative_sums[end] - cumulative_sums[start]
next_sum = cumulative_sums[next_end] - cumulative_sums[end]
next_max_diff = max(max_diff, abs(next_sum - this_sum))
heapq.heappush(
queue, [
next_max_diff,
abs(next_sum - expected_piece_size),
count_completed + 1,
end,
next_end,
start
])
如何将整数数组划分为N个子集,使这些子集的和最小? 例如,数组由11个元素组成,我需要其中的6个子集。 子集:<code>{2,1,1,3},{4},}4,3},}3,2},1,2},{3}</code>最小和=7。 另一个答案是:最小和=7。 注意:在分区时,必须保持数字在原始集合中出现的顺序。
我正在尝试解决此问题: 一位物理教授给班上的学生做项目。学生们必须组成一个两人小组来做这个项目。教授让学生来决定队伍。一个班级的学生人数将是偶数。 每个学生都有自己的知识水平。它告诉每个学生有多少知识。一个团队的知识水平是两个学生知识水平的总和。 学生们决定组成小组,这样知识最高的团队和知识最低的团队之间的差异就最小了。 投入 输入的第一行将包含测试用例的数量t;在接下来的t行中,第一个数字是n,
问题内容: 想象一下,我有一个这样的JS数组: 我想要的是将该数组拆分为N个较小的数组。例如: 对于Python,我有这个: 对于JS,我可以提出的最佳解决方案是递归函数,但我不喜欢它,因为它既复杂又丑陋。这个内部函数返回一个像这样的数组[1,2,3,null,4,5,6,null,7,8],然后我必须再次循环并手动拆分它。(我的第一次尝试是返回此:[1、2、3,[4、5、6,[7、8、9]]],
我想从数组的一部分找到最大值和最小值。我知道我可以通过复制数组将所需的数组部分复制到另一个数组中,但只是想知道是否可以不复制数组,因为我必须为不同的子数组进行循环 例如: 现在我想从1到4找到子数组的最小/最大值(如果可能,不复制子数组)
基本上,我要问的是给定一个正方形2D阵列和一个有效的补丁大小(2D子阵列的大小),我将如何做到这一点。最终,我不需要以任何方式存储子阵列,我只需要找到每个子阵列的中值并将它们存储在一个一维阵列中。中值和存储到新阵列对我来说很简单,我只是不知道如何处理原始2D阵列并正确拆分它。我已经尝试了几次,但一直出现越界错误。我有一个4x4: 我需要像这样拆分它 < code>[1,2] [3,4] [2,3]
假设我有一个包含整数的数组。 如何找到大小的子集,使得子集中所有整数对之间的距离,我的意思是它们在最远的距离。 示例:数组和, ,最小距离为10和6之间的<错误的子集: ,最小距离为 ,最小距离为 我想到了一个解决办法: 1) 排序数组2)选择一个[0],现在在数组中查找ceil(a[0])=Y。。。。然后ceil(Y