就餐问题:
几个家庭一起出去吃饭。为了增加他们的社交互动,他们想坐在桌子旁,以便同一家庭中没有两个成员在同一张桌子上。假设晚餐队有p
个家庭,i
家庭有a(i)
个成员。另外,假设有q
个表可用,j
表的容量为b(j)
。
问题是: 我们可以坐在桌子上的最大人数是多少?
编辑: 创建图表并运行最大流量算法可以解决此问题。但如果我们有D *算法的2 * 10 ^ 3个顶点,则全局复杂度为O(10 ^ 6 * 10 ^ 6)= O(10 ^ 12)。
如果我们只是以贪婪的方式首先坐在较大的群体中。复杂度为O(10 ^ 6)。
所以我的问题是:
1)此问题中的贪婪方法是否有效?
2)解决这个问题的最佳算法是什么?
答案 0 :(得分:3)
是的,贪婪地安置最大的家庭是一个正确的解决方案。我们只需要证明,在我们安排下一个最大的家庭之后,有一种方法可以正确地安置剩下的家庭。
假设一个实例是可解的。我们通过归纳证明,在贪心算法占据k
个最大家族之后,存在一个解决方案。基础k = 0
是显而易见的,因为要证明的假设是存在解决方案。归纳地,假设存在一个扩展贪婪的第一个k - 1
家族的部分分配的解决方案。现在,贪婪通过安置k
家庭来扩展其部分任务。我们编辑已知的解决方案以恢复归纳假设。
虽然我们仍然可以,但找到一张桌子T1
,其中贪婪已经安置了k
家庭成员,但已知的解决方案却没有。如果T1
处的已知解决方案中有空格,请从贪婪没有的表中移动k
家庭成员。否则,已知解决方案的家庭成员不在位于k
的{{1}}最大家庭中。由于该家庭小于T1
最大的家庭,k
最大的家庭成员占据了较小的家庭没有的表k
。交换这些成员。
答案 1 :(得分:2)
很容易想出这样的座位根本不可能的例子,所以这里有一个伪代码来解决问题,假设问题是可以解决的:
Sort each family i by a(i) in decreasing order
Add each table j to a max-heap with b(j) as the key
For each family i from the sorted list:
Pop a(i) tables from max-heap
Add one member of i to each table
Add each table j back into the max-heap with b(j) = b(j) - 1
让n = a(1) + a(2) + ... + a(p)
(即总人数)
假设二进制堆用于最大堆,时间复杂度为:
O(plog(p))
O(qlog(q))
O(nlog(q))
给出O(plog(p) + qlog(q) + nlog(q))
的总时间复杂度,其中O(nlog(q))
可能占主导地位。
由于我们正在处理整数,如果我们为最大堆使用1D桶系统,c
是最大b(j)
,那么我们最终将只使用O(n + c)
(假设最大堆操作占主导地位),这可能更快。
最后,请向大卫的答案进行投票,因为证据是必需的并且非常棒。