问题是这样的(已翻译):
山底有n(n <= 25000)人,每个人都想上山,然后下山。有2个导游:一个用于帮助一个人上山,一个用于帮助一个人下山。我占用(i)时间爬上这座山,然后下来(i)下降它的时间。但是,每个导游一次只能帮助1个人(这意味着最多可以攀爬1个人,并且在任何给定时间最多可以有1个人下山)。假设当“向上”指南到达顶部时,他立即被传送回底部,就像“向下”指南一样。找到让每个人上下山的最短时间。 (如有必要,人们可以聚集在山顶)
以下是问题的示例输入,由我注释:
3 persons
person 1: up=6 minutes, down=4 minutes
person 2: up=8 minutes, down=1 minutes
person 3: up=2 minutes, down=3 minutes
输出到输入:
最短时间是17.这是因为如果第3个人先行,然后是第1人,然后是第2人(同样的顺序是 用于上升和下降),总时间为17。
我尝试过一些算法,但到目前为止我还有这些算法:
O(n!* n)算法:使用next_permutation将所有可能的排列置换为奶牛
一种贪婪的算法:我通过减少下降时间对人进行排序,并尝试将它们放在一起,但这并没有得到正确的解决方案。
其他想法
我现在转向动态编程,因为根据CLR,优化问题通常是贪婪或动态编程(我认为这个问题满足最佳子结构)。
我注意到,在最小的解决方案中,“向上”指南在每个人都上山之前都不会休息。 (所以人1的上升,人2的上升等之间没有差距。)也许问题可以减少到最小化下降时间之间的差距?
我无法想象这个动态编程问题的状态,(我不认为它是单维的,因为我不认为你能找到最适合我的人的解决方案,因为我知道i-的最佳解决方案1人)。
有人可以帮忙吗?
答案 0 :(得分:5)
此问题相当于具有完工时间目标的n-job 2机器流水车间问题(n / 2 / F / C max )。 Johnson's algorithm找到了一个确切的解决方案。
答案 1 :(得分:-1)
只有降序指导空闲时间才真正重要。在考虑之后,我认为这里的主要问题是选择第一个爬上去的人,因为第一个登山者的时间肯定是导致降序的延迟。
解决方法可能是选择up(i)
中down(i) > up(i)
最低{{}}}的那个,然后通过down(i) > up(i)
,然后down(i) = up(i)
优先选择所有人,然后全部其余的部分。对于下降,您只需优先考虑最长时间(i)的人。
这实现了: