如果我给出了最大重量,说w = 20。我已经给出了一组重量,比如说m = [5,7,12,18]那么我怎么能计算出我们可以容纳的最大重量?使用m的最大重量。在这种情况下,答案是19.通过添加12 + 7 = 19。我的代码给了我18.请帮助我。
int weight(int W, vector<int> &m) {
int current_weight = 0;
int temp;
for (int i = 0; i < w.size(); i++) {
for (int j = i + 1; j < m.size(); j++) {
if (m[i] < m[j]) {
temp = m[j];
m[j] = m[i];
m[i] = temp;
}
}
}
for (size_t i = 0; i < m.size(); ++i) {
if (current_weight + m[i] <= W) {
current_weight += m[i];
}
}
return current_weight;
}
答案 0 :(得分:2)
您描述的问题看起来更像maximum subset sum问题的版本。基本上,你的实施首先没有任何问题;显然你已经正确地实现了问题的贪婪算法。话虽如此,该算法无法为每个输入生成最佳解决方案。你找到的实例就是这样一个例子。
然而,问题可以使用称为dynamic programming的不同方法来解决,这可以被视为解决方案的递归公式的组织形式。
让m = { m_1, ... m_n }
成为正项目大小的集合,W
成为封顶约束,其中n
是正整数。将数组A[n][W]
组织为状态空间
A[i][j] = the maximum weight at most j attainable for the set of items
with indices from 0 to i if such a solution exists and
minus infinity otherwise
每个i in {1,...,n}
和j in {1,...,W}
的;为了便于呈现,假设A
在其他任何地方都具有负无穷大的值。请注意,对于每个此类i
和j
重复关系
A[i][j] = min { A[i-1][W-m_j] + m_j, A[i-1][W] }
成立,第一种情况对应于在解决方案中选择项目i
,第二种情况对应于不选择项目i
到解决方案中。
接下来,组织一个循环,按照i
和j
值增加的顺序填充此表,其中i = 1
的初始化必须在此之前完成。填充状态空间后,最后一个列中的最大可行值
max{ A[n][j] : j in {1,...,W}, A[n][j] is not minus infinity }
产生最佳解决方案。如果还需要相关的项目集,则必须使用一些回溯或合适的辅助数据结构。
答案 1 :(得分:0)
因此,通过将权重数组的副本作为值数组传递,可以感觉到此解决方案可以对常见的0-1 knapsack problem进行微不足道的更改。