在当前项目中,人们可以订购送货上门的商品,并选择“付款时付款”作为付款选项。为了确保交付人员有足够的变化,客户被要求输入他们将支付的金额(例如,交付是48,13,他们将支付60, - (3 * 20, - ))。现在,如果它取决于我,我会把它变成一个自由的领域,但是已经决定应该是基于可用面额的选择,而不给出会导致一组面额可能更小的金额。
示例:
denominations = [1,2,5,10,20,50]
price = 78.12
possibilities:
79 (multitude of options),
80 (e.g. 4*20)
90 (e.g. 50+2*20)
100 (2*50)
它是国际性的,所以面额可能会改变,算法应该基于该列表。
我最接近的似乎有效:
for all denominations in reversed order (large=>small)
add ceil(price/denomination) * denomination to possibles
baseprice = floor(price/denomination) * denomination;
for all smaller denominations as subdenomination in reversed order
add baseprice + (ceil((price - baseprice) / subdenomination) * subdenomination) to possibles
end for
end for
remove doubles
sort
似乎可以工作,但是在经过各种紧凑算法的尝试之后就出现了这种情况,我无法为为什么保护它起作用,这可能导致一些优势 - 案例/新国家选择错误,并确实产生了大量的双打。
因为这可能不是一个新问题,而谷歌等人。无法为我提供答案除了计算如何进行精确更改的大量页面之外,我想我会问:你之前解决了这个问题吗?哪种算法?任何证据都会一直有效吗?
答案 0 :(得分:2)
它是贪婪算法的应用http://mathworld.wolfram.com/GreedyAlgorithm.html(一种用于从最小可能的组成部分递归构造一组对象的算法)
伪代码
list={1,2,5,10,20,50,100} (*ordered *)
while list not null
found_answer = false
p = ceil(price) (* assume integer denominations *)
while not found_answer
find_greedy (p, list) (*algorithm in the reference above*)
p++
remove(first(list))
编辑>一些迭代是无意义的>
list={1,2,5,10,20,50,100} (*ordered *)
p = ceil(price) (* assume integer denominations *)
while list not null
found_answer = false
while not found_answer
find_greedy (p, list) (*algorithm in the reference above*)
p++
remove(first(list))
编辑>
我发现由于Pearson对Greedy算法的改进。其O(N ^ 3 log Z),其中N是面额数,Z是该集合中最大的账单。
中找到它答案 1 :(得分:0)
您可以在数据库中生成所有可能的付费硬币和纸张组合(英语不是很好),每行包含此组合的总和。
拥有这个数据库,您可以通过一个查询简单地获得所有可能的过度支付,
WHERE sum >= cost and sum <= cost + epsilon
关于epsilon的一些话,嗯..你可以从成本价值中分配它吗?也许10%的成本+ 10美元?:
WHERE sum >= cost and sum <= cost * 1.10 + 10
表格结构必须包含表示硬币数量和纸张类型的列数。 每列的值包含此类付费项目的出现次数。
这不是这个问题的最佳和最快的解决方案,但实现简单易行。 我想更好地解决这个问题。
您可以从 cost
到cost + epsilon
的其他方式,并为每个值计算每个值的最小可能付费项目数。我有它的算法。您可以使用此算法执行此操作,但这是在C ++中:
int R[10000];
sort(C, C + coins, cmp);
R[0]=0;
for(int i=1; i <= coins_weight; i++)
{
R[i] = 1000000;
for (int j=0; j < coins; j++)
{
if((C[j].weight <= i) && ((C[j].value + R[i - C[j].weight]) < R[i]))
{
R[i] = C[j].value + R[i - C[j].weight];
}
}
}
return R[coins_weight];
击> <击> 撞击>