假设有s_1,s_2,...,s_n
个苹果卖家,根据我们购买的金额,价格会有所不同,而卖家j购买i苹果的价格是p(i,j)。找到一种以最低成本准确购买苹果(0 <= A <= kn
)的方法是什么?我认为需要构建一个M * n表来开发动态编程算法,但我不确定如何设计它。而且,我认为时间复杂度应该是O(n ^ 2 k ^ 2),我是否正确?
后续问题:如果我们从卖家j购买u
个苹果,我们不允许从其邻居(u+2
和s_j-1
购买s_j+1
个或更多苹果),在这种情况下我们应该如何设计算法?
由于
答案 0 :(得分:2)
问题1所需的数据结构,对于j
中的1..n
和k
中的0..A
,您可以花费的最低金额{ {1}}来自第一批k
供应商的苹果,以及您从最后一批供应商购买的数量。计算单个供应商的数据,假设您拥有最后一个,j
n O(A)
O(A ^ 2 * n)O(A) counts. Do that for
每个vendors and you need
操作需要time. With some cleverness, you can also make it
次操作O(A ^ 2)`记忆。
对于问题2,它变得更加棘手。而不是通过供应商j
购买的每个苹果数量的数据结构,它必须是每(j, k)
个数据结构,因为它对您购买的苹果数量很重要。这使得它O(A^3*n)
时间。 (实际上比这更好,因为你从不从任何一个供应商那里买太多苹果。)
答案 1 :(得分:2)
这个问题可以很好地转换为常见的背包问题,除了您为每个“项目”设置了许多不同的“价格”和“权重”,即您的p(i,j)
功能。
从the Wikipedia page无耻地复制的标准DP算法如下所示:
// Input:
// Values (stored in array v) -> represented by p function
// Weights (stored in array w) -> determined by parameter to p
// Number of distinct items (n) -> different apple suppliers
// Knapsack capacity (W) -> desired number of apples A
for j from 0 to W do:
m[0, j] := 0
for i from 1 to n do:
for j from 0 to W do:
if w[i] > j then:
m[i, j] := m[i-1, j]
else:
m[i, j] := max(m[i-1, j], m[i-1, j-w[i]] + v[i])
但是有一些不同之处:
max
值,而是在寻找min
价格W
苹果,但完全 W
苹果(否则,最好的策略是不买任何苹果苹果)p(i, j)
因此,您可以将算法调整为这样的(使用类似Python的列表理解符号)
for j from 0 to W do: // apples to buy from seller 1
m[1, j] := p(1, j)
for i from 2 to n do: // loop sellers 2 to n
for j from 0 to W do: // loop total number of apples to buy
m[i, j] := min(m[i-1, j-k] + p(k, i)
for k from 0 to j) // apples bought from seller i
这意味着你有三个嵌套循环,这使得复杂度为O(nA²)。
第二部分有点棘手,我不确定我是否真的理解它。基本上,这意味着对于每个卖家(第一个除外),您只能再购买一个,相同数量,或者比前一个卖家少一个。为此,您必须扩展DP矩阵以具有第三个维度,即从该卖家购买的苹果数量,并将min
表达式替换为实际循环,分配给该表的不同单元格。