我了解用于硬币找零问题的贪婪算法(如何用尽可能少的硬币数目支付一定的金额)如何工作-它总是选择面额最大的硬币而不超过剩余金额-并且总是能找到正确的解决方案特定的硬币套。
但是对于某些硬币集,贪婪算法的总和会失败。例如,对于集合{1, 15, 25}
和总和30,贪婪算法首先选择25,剩下的余数为5,然后选择5个1表示总共6个硬币。但是,使用最少数量的硬币的解决方案是选择15次两次。
一组硬币必须满足什么条件,以便贪婪算法找到所有和的最小解?
我了解用于硬币找零问题的贪婪算法(如何用尽可能少的硬币数目支付一定的金额)如何工作-它总是选择面额最大的硬币而不超过剩余金额-并且总是能找到正确的解决方案特定的硬币套。
但是对于某些硬币集,贪婪算法的总和会失败。例如,对于集合{1, 15, 25}
和总和30,贪婪算法首先选择25,剩下的余数为5,然后选择5个1表示总共6个硬币。但是,使用最少数量的硬币的解决方案是选择15次两次。
一组硬币必须满足什么条件,以便贪婪算法找到所有和的最小解?
Answers:
可以通过使用贪婪方法来构成拟阵(https://en.wikipedia.org/wiki/Matroid)来解决硬币兑换问题。简而言之,拟阵是满足以下条件的有序对M =(S,l):
在我们的硬币更换问题中,S是按降序排列的所有硬币的集合。我们需要通过S中最少的硬币个数来获得V的值
在我们的例子中,l是一个包含所有子集的独立集合,因此对于每个子集,以下内容均成立:它们中的值之和为<= V
如果我们的集合是拟阵,那么我们的答案是l中的最大集合A,其中不能再添加x
为了进行检查,我们看一下拟阵的属性是否在集合S = {25,15,1}中成立,其中V = 30现在,l中有两个子集:A = {25}和B = {15,15} | A | <| B |,那么有一些元素x-> BA使得AU {x}-> l(根据3)因此,{25,15}应该属于l,但这是自25 + 15> 30以来的矛盾
因此,S不是拟阵,因此贪婪方法对它无效。
在任何情况下,如果没有硬币的价值加到最低面额的硬币都比面额的两倍小,且硬币的面额立即小于硬币的面额,贪婪算法就会起作用。
即{1,2,3}之所以起作用是因为[1,3]和[2,2]相加相同的值,但是{1,15,25}不起作用是因为(对于更改30)15 + 15> 25 +1
这是一个复发问题。给定一组硬币{Cn, Cn-1, . . ., 1}
,例如,1 <= k <= n, Ck > Ck-1
如果Ck> Ck-1 + Ck-2,则贪婪算法将产生最少数量的硬币,对于该值V=(Ck + Ck-1) - 1
,将贪婪算法应用于硬币的子集{Ck, Ck-1, . . ., 1}
,其中Ck <= V
导致硬币的数量大于将贪婪算法应用于硬币子集的数量{Ck-1, Ck-2, . . ., 1}
。
测试很简单:对于`1 <= k <= n,测试贪婪算法针对Ck + Ck-1-1的值生成的硬币数量。对硬币集{Ck,Ck-1,。。。,1}和{Ck-1,Ck-2,。。。,1}。如果对于任何k,后者产生的硬币数量均少于前者,则贪婪算法将不适用于该硬币组。
例如,在n = 4的情况下,考虑硬币集{C4,C3,C2,1} = {50,25,10,1}。从k = n = 4开始,然后V = Cn + Cn-1-1 = 50 + 25-1 = 74作为测试值。对于V = 74,G {50,25,10,1} = 7个硬币。G {25,10,1} = 8个硬币。到现在为止还挺好。现在让k = 3。那么V = 25 + 10-1 = 34。G {25,10,1} = 10个硬币,但G {10,1} = 7个硬币。因此,我们知道贪婪算法不会最小化硬币集{50,25,10,1}的硬币数量。另一方面,如果我们向此硬币组添加一个小点,则G {25,10,5,1} = 6且G {10,5,1} =7。同样,对于V = 10 + 5-1 =在图14中,我们得到G {10,5,1} = 5,但是G {5,1} =6。所以,我们知道,贪婪在{50,25,10,5,1}起作用。
这就引出了一个问题:满足贪婪算法的硬币面额应该是多少,这对于从1到100的任何值,导致最坏情况的硬币数量最少?答案很简单:100个硬币,每个硬币的取值范围从1到100。这可以说不是很有用,因为它可以在每次交易中线性搜索硬币。更不用说铸造许多不同面额并追踪它们的开销了。
现在,如果我们要首先最小化面额数量,然后第二次最小化Greedy产生的从1到100的任何值的最终硬币数量,则硬币的2的次幂:{64,32,16,8,4 、、 2、1}的结果是:对于任何值1:100(7位数字中最大1的数目,其值小于十进制100),最多产生6个硬币。但这需要7种面额的硬币。这五个面额{50,25,10,5,1}的最坏情况是8,发生在V = 94和V = 99。幂为3 {1、3、9、27、81}的硬币也只需要5个面额的格里迪币即可使用,但最差的情况是产生8个面额为62和80的硬币。最后,使用这5个面额中的任何一个{64、32、16、8、4、2、1}的子集,不能排除'1'并且满足贪婪,也将导致最多8个硬币。因此,存在线性权衡。将面额数量从5增加到7会减少表示1到100之间的任何值所需的最大硬币数量从8减少到6。
另一方面,如果您想最大程度地减少买卖双方之间交换的硬币数量,假设它们各自的口袋中每种面额至少有一个硬币,那么这个问题就等于平衡任何硬币所需的重量最少。重量从1到N磅。事实证明,如果以3的幂给出硬币面额,则购买中交换的硬币数量最少。{1, 3, 9, 27, . . .}
。
参见/puzzling/186/whats-the-fewest-weights-you-need-to-balance-any-weight-from-1-to-40-pounds。
如果由贪婪算法改变而给出的硬币数量对于所有数量都是最佳的,则硬币系统是规范的。
本文提供了一种O(n ^ 3)算法来确定硬币系统是否规范,其中n是不同种类硬币的数量。
对于非规范的硬币系统,c
贪婪算法会产生一定数量的次优硬币。c
被称为反例。如果最小的反例大于最大的单个硬币,则该硬币系统是紧密的。
今天,我在Codeforces上解决了与此类似的问题(链接将在最后提供)。我的结论是,要使硬币找零问题能够由Greedy alogrithm解决,它应满足以下条件:
1.按升序对硬币值进行排序时,大于当前元素的所有值都应被当前元素整除。
例如硬币= {1,5,10,20,100},这将给出正确的答案,因为{5,10,20,100}都可被1整除,{10,20,100}都可被5整除,{ 20,100}全部可被10整除,{100}全部可被20整除。
希望这能给您一些想法。
996 A-打彩票 https://codeforces.com/blog/entry/60217
一个容易记住的情况是,任何一组硬币,如果它们按升序排序并且您具有:
coin[0] = 1
coin[i+1] >= 2 * coin[i], for all i = 0 .. N-1 in coin[N]
然后使用这种硬币的贪婪算法将起作用。
根据您查询的范围,可能会有更好的分配(根据所需硬币的数量)。例如,如果您正在考虑范围(6..8),并且您使用硬币<6,7,8>而不是<1,2,4,8>。
在N +上完成的硬币的最有效分配是与上述规则相等,给您硬币1,2,4,8 ...; 仅仅是任何数字的二进制表示。从某种意义上说,碱基之间的对话本身就是一种贪婪算法。
在此讨论中,Max Rabkin提供了关于> = 2N不等式的证明:http : //olympiad.cs.uct.ac.za/old/camp0_2008/day1_camp0_2008_discussions.pdf
{ 25, 10, 1 }
符合“至少是先前硬币的两倍”的条件,但对于总共30个,贪婪算法将得出25+ 5 * 1(6个硬币),而最佳解决方案是3 * 10(3个硬币)。-1。