我遇到问题的问题如下:
给定一个N个项目的队列,每个项目都有一个权重,以及K个容器的队列。我们需要按照它们的顺序将项目分区到容器。例如,第一个项目只能转到第一个容器,第二个项目可以转到第一个或第二个容器而不是第三个容器(否则第二个容器将没有任何项目)。
我需要创建并实现一种算法来进行某种均匀分布,因此最重的容器必须尽可能轻量级;计算具有这种重量的容器。
我认为这是3分区或背包问题的一些变化。我已经使用动态编程实现了一种可能的分发解决方案,并尝试从其中使用的表中获取计数。但它不够有效(内存太贵),并且获取容器数量的算法不正确。
有人可以解释一下,哪种算法可以解决这个问题?
答案 0 :(得分:1)
因此,OP的问题一般可以通过this question中给出的DP算法来解决。为了完整起见,我将在此重复它的关键:
当我们有项目 s [1],..,s [i] 时,假设 d [i] [j] 是问题的解决方案 和 j 容器。然后:
- d [0] [j] = 0 每个 j
- d [i] [1] = Sum(s [1],...,s [i]) for 每个我
- d [i] [j] = min(max(d [it] [j-1],Sum(s [i-t + 1],...,s [i]) 1·; = T< = I)
醇>
然而,天真的实现消耗O(NK)空间,这太多了。幸运的是,请看(3):d[_][j]
的值仅取决于d[_][j-1]
。这意味着,一旦我们完成了所有d[_][j]
的计算,我们就可以使用我们用来存储d[_][j-1]
的空间来存储我们即将计算的d[_][j+1]
的值。< / p>
由于值d[0][j]
都为零,我们也不需要存储它们。因此,我们需要存储的唯一数组是O(N)大小的d[i][1]
,O(N)大小的数组,它保存j-1
次迭代的结果,以及O(N) -sized数组,用于保存我们当前正在计算的j
次迭代的结果。总计:O(N)。
编辑:所以第一次,我实际上没有回答关于如何计算最大重量的容器数量的OP的问题。假设w[i][j]
保持i,j
问题的最大权重,c[i][j]
是与最大权重匹配的容器数。然后:
c[0][j] = j
w[0][j] = 0
和j
每个c[i][1] = 1
w[i][1] = Sum(s[1], .., s[i])
和i
u
等于上面pt(3)中选择的t
。
d[i-u][j-1] > Sum(s[i-u+1], .., s[i])
:
c[i][j] = c[i-u][j-1]
和w[i][j] = w[i-u][j-1]
j
的{{1}}容器比容器Sum(s[i-u+1], .., s[i]
中最重的容器轻,其容器1, .., j-1
。 d[i-u][j-1]
:
d[i-u][j-1] < Sum(s[i-u+1], .., s[i])
和c[i][j] = 1
w[i][j] = Sum(s[i-u+1], .., s[i])
项的j
容器是新的最重容器。s[i-u+1], .., s[i]
:
d[i-u][j-1] == Sum(s[i-u+1], .., s[i])
和c[i][j] = c[i-u][j-1]+1
w[i][j] = d[i-u][j-1]
容器的重量与之前最重的容器相同。同样,我们只需要使用恒定数量的j
大小的数组,总时间O(N)
。