这是您的算法挑战,
我有[0..100]
个数字对的列表,我需要找到最大个唯一&#34; 左数< / EM>&#34;同时确保不超过3 的&#34; 正确的号码&#34;。
这是一个例子
(1, 1)
(2, 1)
(3, 1)
(4, 1)
(5, 1)
(6, 1)
(7, 1)
(1, 2)
(4, 2)
(1, 3)
(2, 3)
(5, 4)
结果将是: 7 。我们将采取:(3, 1)
,(6, 1)
,(7, 1)
,(1, 2)
,(4, 2)
,(2, 3)
和(5, 4)
。
无论出于何种原因,我似乎找不到任何其他方式而不是粗暴强迫它......
非常感谢任何帮助:)
答案 0 :(得分:2)
您可以将此问题表达为最大流量问题:
使容量1的边缘从源节点到左侧的每个数字。
将容量3的边缘从每个正确的数字扩展到汇聚节点。
为每对形式(a,b)从左数字a到右数字b创建容量1的边缘。
计算此网络中从源到接收器的最大流量。
答案 1 :(得分:0)
如果有人对此实施感兴趣,请参阅push–relabel maximum flow algorithm
的relabel-to-front
选项规则的红宝石版本。
def relabel_to_front(capacities, source, sink)
n = capacities.length
flow = Array.new(n) { Array.new(n, 0) }
height = Array.new(n, 0)
excess = Array.new(n, 0)
seen = Array.new(n, 0)
queue = (0...n).select { |i| i != source && i != sink }.to_a
height[source] = n - 1
excess[source] = Float::INFINITY
(0...n).each { |v| push(source, v, capacities, flow, excess) }
p = 0
while p < queue.length
u = queue[p]
h = height[u]
discharge(u, capacities, flow, excess, seen, height, n)
if height[u] > h
queue.unshift(queue.delete_at(p))
p = 0
else
p += 1
end
end
flow[source].reduce(:+)
end
def push(u, v, capacities, flow, excess)
residual_capacity = capacities[u][v] - flow[u][v]
send = [excess[u], residual_capacity].min
flow[u][v] += send
flow[v][u] -= send
excess[u] -= send
excess[v] += send
end
def discharge(u, capacities, flow, excess, seen, height, n)
while excess[u] > 0
if seen[u] < n
v = seen[u]
if capacities[u][v] - flow[u][v] > 0 && height[u] > height[v]
push(u, v, capacities, flow, excess)
else
seen[u] += 1
end
else
relabel(u, capacities, flow, height, n)
seen[u] = 0
end
end
end
def relabel(u, capacities, flow, height, n)
min_height = Float::INFINITY
(0...n).each do |v|
if capacities[u][v] - flow[u][v] > 0
min_height = [min_height, height[v]].min
height[u] = min_height + 1
end
end
end
这是将数字对转换为数组
的容量数组的代码user_ids = Set.new
post_ids = Set.new
pairs.each do |p|
user_ids << p[:user_id]
post_ids << p[:post_id]
end
index_of_user_id = {}
index_of_post_id = {}
user_ids.each_with_index { |user_id, index| index_of_user_id[user_id] = 1 + index }
post_ids.each_with_index { |post_id, index| index_of_post_id[post_id] = 1 + index + user_ids.count }
source = 0
sink = user_ids.count + post_ids.count + 1
n = sink + 1
capacities = Array.new(n) { Array.new(n, 0) }
# source -> user_ids = 1
index_of_user_id.values.each { |i| capacities[source][i] = 1 }
# user_ids -> post_ids = 1
pairs.each { |p| capacities[index_of_user_id[p[:user_id]]][index_of_post_id[p[:post_id]]] = 1 }
# post_ids -> sink = 3
index_of_post_id.values.each { |i| capacities[i][sink] = 3 }