我遇到问题的问题如下:
假设我有一个给定重量的存钱罐,并且我使用一组给定的硬币在里面存钱。最后,我知道了存钱罐的总重量以及我使用的硬币的重量和价值。
我想知道我可以保证在存钱罐中的最低金额,即最坏的情况。例如,如果:
然后我可以保证银行的最低价值是60。
问题是背包变体,但我无法找到正确的复发。
提前致谢!
答案 0 :(得分:1)
我接近这个的方法是评估集合中的每个硬币以确定其“价值密度”(因为缺少更好的术语) - 值除以重量。在您的示例中,第一枚硬币的值密度为1,然后第二枚硬币的值密度为30/50 = 0.6。
然后从总重量为零开始,在不超过给定重量的情况下应用最低的“值密度”硬币。然后应用下一个最低的“值密度”硬币,依此类推,直到达到给定的重量。
这是一个贪婪的算法。
答案 1 :(得分:0)
一般背包问题AFAIK只有指数解决方案。也就是说,假设您拥有每种类型硬币的特定数量。在最一般的情况下,你将不得不尝试所有可能的组合(当然不超过总体重量)。
递归算法如下所示:
const int N = /* type count*/;
const int g_Weight[N] = { ... };
const int g_Value[N] = { ... };
int CalcMinValueFrom(int weight, int i)
{
int valBest = 0, valMy = 0;
if (weight <= 0)
return 0; // weight already reached
if (i >= N)
return -1; // out of coins
while (true)
{
int valNext = CalcMinValueFrom(weight, i+1);
if (valNext >= 0)
{
valNext += valMy;
if (!valBest || (valBest > valNext))
valBest = valNext;
}
valMy += g_Value[i];
weight -= g_Weight[i];
if (valBest && (valBest <= valMy))
return valBest;
}
}
// Returns the minimum value for the given weight
int CalcMinValue(int weight)
{
return CalcMinValueFrom(weight, 0);
}
然而,在特定情况下,存在更好的解决方案。如果重量远大于任何硬币的重量,那么您可以轻松地粗略估计结果。为每个硬币定义其“效率”作为其价值和重量之间的比率。为了最小化价值,你应该只选择效率最低的硬币。此解决方案精确到“边缘效应”,例如四舍五入等(意味着 - 您只能获取整数个硬币)。
答案 2 :(得分:0)
显然你知道这个问题,但你想找到一种方法来计算解决方案^^。
对于精确的方法,您可以检查分支和绑定算法。这是一个相对简单的OR方法,可以找到背包问题的精确解决方案,你应该找到很多课程。
Vicky提出了一个很好的解决方案来计算分支定界算法的下限。