Algorithm 最大硬币分割
自从昨天站在超级市场的销售点,再次尝试试探性地找到我的硬币的最佳分割,同时试图忽略我身后不耐烦和紧张的队列,我一直在思考潜在的算法问题: 给定一个硬币系统,其值为v1,…,vn,有限数量的硬币a1,…,an和我们需要支付的金额s。Algorithm 最大硬币分割,algorithm,greedy,data-partitioning,Algorithm,Greedy,Data Partitioning,自从昨天站在超级市场的销售点,再次尝试试探性地找到我的硬币的最佳分割,同时试图忽略我身后不耐烦和紧张的队列,我一直在思考潜在的算法问题: 给定一个硬币系统,其值为v1,…,vn,有限数量的硬币a1,…,an和我们需要支付的金额s。 我们正在寻找一种算法来计算一个分区x1,…,xn(如果我理解正确,这基本上是的一个变体。如果我们假设每个硬币都有一个(a[I]=1,对于每个I),那么你会这样解决它: sum[0] = true for i = 1 to n do for j = maxSum
我们正在寻找一种算法来计算一个分区x1,…,xn(如果我理解正确,这基本上是的一个变体。如果我们假设每个硬币都有一个(
a[I]=1
,对于每个I
),那么你会这样解决它:
sum[0] = true
for i = 1 to n do
for j = maxSum downto v[i] do
sum[j] |= sum[j - v[i]]
然后找到第一个k>=s
和sum[k]
是true
。你可以通过跟踪每个sum[j]
贡献了哪些硬币来获得实际使用的硬币。使用你的硬币得到的金额越接近s
,变化就越少,这就是你想要的
现在你没有一枚硬币i
,你有一枚硬币i
。我建议:
sum[0] = true
for i = 1 to n do
for j = maxSum downto v[i] do
for k = 1 to a[i] do
if j - k*v[i] >= 0 do
sum[j] |= sum[j - k*v[i]] <- use coin i k times
sum[0]=true
对于i=1到n do
对于j=maxSum到v[i]do
对于k=1到a[i]do
如果j-k*v[i]>=0 do
sum[j]|=sum[j-k*v[i],如果您始终随身携带的硬币数量尽可能低(如果您以前每次在超市玩此游戏),然后你可以用给你所有硬币的方法来计算它,然后计算会给你什么,并从你现在的物品中减去这些零钱。@BoBoBoBoBoBoBo我不认为这会被认为是一个,这是一个相当普遍的问题,不适用于cstheory。你的硬币面额是多少?它们是否会让贪婪的人找零钱的算法总是给出最少的硬币数?@eumiro:是的,我也偶然发现了这个解决方案,但我还不确定它是否能满足所有情况(特别是如果出纳返回的s+1的金额可能比s少)…非常感谢@IVlad-非常好的解决方案和很好的解释!事实上,我在脑海中的某个地方也有子集问题,但没有找到解决方案。剩下的唯一问题是:我们能否始终确保更改最少的解决方案是正确的?是否可能存在一个分区,其中我们有更多的change,但最终得到的硬币比解决方案中的硬币要少,变化很小?我在考虑一个变化,比如4美分,至少需要2枚硬币(2x2)而5美分的兑换只需要1枚硬币…@Toby-这是真的,很好。要解决这一问题,您必须将k
从s
迭代到maxSum
,并对每个sum[k]=true
,在k-s
上运行最小数量的硬币换币算法,并保持最小值。我意识到这不是很有效,但这是我迄今为止得到的所有结果。我会再仔细考虑一下,然后让你知道我是否能想出更好的方案。