请在下面找到问题,解决方案及其工作实施。下面的解决方案的时间复杂度为O(n!)(如果我错了,请纠正我。)
1)请建议一个时间复杂度更高的解决方案。鉴于它是一个优化问题,动态编程或memoization似乎是一个更好的选择。另外,请提供一个分析,证明您的解决方案的时间复杂性。谢谢!
管道公司生产固定长度的管道n。它获得了k个管道的订单,每个管道的长度在每天(0,n)之间。编写一个算法,帮助公司使用最小数量的固定长度的管道来完成订单。
对于k个订单,请考虑所有排列。对于每个排列,贪婪地计算成本。以最低成本选择排列。 我们需要两种数据结构:1)顺序:使用列表2)成本:包含所有管道的列表,其中value是管道的剩余长度。 如果我们使用长度为n的单个管道,则表示成本的数据结构为[0]。
#IMPLEMENTATION OF Solution1
import itertools
n = 10
def fulfill_element_greedily(pipes_used, order):
eligible_pipes = filter(lambda x : x - order >= 0, pipes_used)
if len(eligible_pipes) == 0:
new_pipe_used = n-order
else:
eligible_pipes.sort(reverse=True)
new_pipe_used = eligible_pipes[-1] - order
pipes_used.remove(eligible_pipes[-1])
return pipes_used + [new_pipe_used]
def cost_for_greedy_fulfill(orders):
pipes_used = []
for order in orders:
pipes_used = fulfill_element_greedily(pipes_used, order)
return len(pipes_used)
def min_cost(orders):
if(any(map(lambda x : x > n,orders))):
print "Orders %s" % str(orders)
raise ValueError("Invalid orders")
return min(map(cost_for_greedy_fulfill,itertools.permutations(orders))) if len(orders)!=0 else 0
def test():
assert 0 == min_cost([])
assert 1 == min_cost([1])
assert 1 == min_cost([5])
assert 1 == min_cost([10])
assert 2 == min_cost([10,2])
assert 2 == min_cost([2,9,7])
assert 2 == min_cost([1,7,9,3])
return "tests passed"
print test()
#IMPLEMENTATION OF Solution1
import itertools
n = 10
def fulfill_element_greedily(pipes_used, order):
eligible_pipes = filter(lambda x : x - order >= 0, pipes_used)
if len(eligible_pipes) == 0:
new_pipe_used = n-order
else:
eligible_pipes.sort(reverse=True)
new_pipe_used = eligible_pipes[-1] - order
pipes_used.remove(eligible_pipes[-1])
return pipes_used + [new_pipe_used]
def cost_for_greedy_fulfill(orders):
pipes_used = []
for order in orders:
pipes_used = fulfill_element_greedily(pipes_used, order)
return len(pipes_used)
def min_cost(orders):
if(any(map(lambda x : x > n,orders))):
print "Orders %s" % str(orders)
raise ValueError("Invalid orders")
return min(map(cost_for_greedy_fulfill,itertools.permutations(orders))) if len(orders)!=0 else 0
def test():
assert 0 == min_cost([])
assert 1 == min_cost([1])
assert 1 == min_cost([5])
assert 1 == min_cost([10])
assert 2 == min_cost([10,2])
assert 2 == min_cost([2,9,7])
assert 2 == min_cost([1,7,9,3])
return "tests passed"
print test()
答案 0 :(得分:0)
复杂度O(k *(2 ^ k))的动态规划算法如下:
定义包含以下2个成员的状态:
struct State {
int minPipe; // minimum number of pipes
int remainingLen; // remaining length of last pipe
}
当且仅当
时,我们说状态a优于状态b(a.minPipe < b.minPipe) or (a.minPipe == b.minPipe && a.remainingLen > b.remainingLen)
问题本身可分为2 ^ k个状态:
State states[2^k]
其中states [i]表示已经产生管道x的最佳状态(最后管道的最大剩余长度的管道的最小数量),(1&lt; = x&lt; = k),其中二进制中的第x位i的表示被设定。
例如,
states[0]: inital state, no pipe produced
states[1]: optimal state with only the 1st pipe produced
states[2]: optimal state with only the 2nd pipe produced
states[3]: optimal state with the 1st and 2nd pipe produced
states[4]: optimal state with only the 3rd pipe produced
...
通过处理每个状态x的所有先前状态:
状态[x] =从所有可能的先前状态y转移的最佳状态,其中x> y并且x和y的二进制表示之间只有1位差异。
最终答案来自州[2 ^ k - 1] .minPipe;
复杂性:每个状态最多具有(k-1)个先前状态,其中有2 ^ k个状态,因此最终复杂度为O(k * 2 ^ k),小于O(k!)< / p>