当前位置: 首页 > 知识库问答 >
问题:

优化变更解决方案

吕骞尧
2023-03-14

我在这里编写了一个Python解决方案,它解决了以下问题:如何用最少数量的给定面额的硬币来制造给定数量的货币?

def min_coin_change(n, d):
    mini = float("inf")
    for den in d:
        diff = n - den
        if diff == 0:
            ans = 1
        elif diff < 0:
            ans = float("inf")
        else:
            ans = 1 + min_coin_change(n - den, d)
        mini = min(mini, ans)
    return mini

虽然我的解决方案有效,但当n大于50或d的长度大于5时,需要很长时间。我怎样才能加快代码的速度,使其能够在相当大的输入下工作?我是否错过了一个技巧或其他可以大大加快代码速度的东西?

共有3个答案

岑光熙
2023-03-14

这是因为它是递归

阅读这个什么是记忆化,我如何在Python中使用它?(和前两个答案)

“记忆化”会记住你已经计算过的东西(比如10美分),这样你就不会以指数级的次数重新计算它们。

您可以按原样复制Mwmoize类,只需“装饰”您的函数,如第二个答案中所述

懒人

class Memoize:
    def __init__(self, f):
        self.f = f
        self.memo = {}
    def __call__(self, *args):
        if not args in self.memo:
            self.memo[args] = self.f(*args)
        return self.memo[args]

然后在定义前添加装饰器

@Memoize
def min_coin_change(n,d)......

函数的其余部分是相同的

那你叫它

min_coin_change(30,(25,10,5,1))
左丘阳晖
2023-03-14

请注意,您应该将函数设置为从最大的硬币开始,循环查找最大可能数量的最大硬币,然后重复下一个最大的硬币。

因此,den应按降序排序

def changecoin(d, denval)
  count = 0
  while d > denval:
    d -= denval
    count += 1
  return count, d

现在调用具有下一个最低值denval和新值d的递归,并适当地增加计数。

newcount = 0
for denval in den:
    count, d = changecoin(d, denval)
    newcount += count

实际上,在代码中,可以通过省略而在某种程度上修复Changecoin函数,这样就可以编写内联代码

count = 0
for denval in den
  count += d//denval
  d = d % denval

这将返回计数和d中剩余的任何值。如果d小于denval,计数增量将为0,剩余的d不变。当d变为0时,for循环没有中断,但den中几乎没有足够的条目可以忽略测试

  if d < 1:
    break
魏安宁
2023-03-14

我们能假定硬币的面额是合理的吗?这个问题的一般情况是允许出现奇怪的硬币面额,如[100,90,1],而简单的“贪婪”算法不会找到最优解(例如,对于180,最优解是两个90美分的硬币,而简单的贪婪算法会建议一个100美分的硬币和80美分的硬币)。

如果我们可以假设合理的货币(就像任何实际货币一样),那么我建议你使用整数除法和模数的组合来计算每枚硬币的使用数量。

如果我们不能假设合理的货币,那么这个问题是动态规划解决方案的理想选择。在动态规划中,您构建一个记录中间结果的表,与简单的递归解决方案相比,这节省了大量时间。

Skiena的书《Alog算法设计手册》中对动态编程有一个很好的解释。

http://www.algorist.com/

以下是我在网上找到的一些链接:

http://www.avatar.se/molbioinfo2001/dynprog/dynamic.html

http://www.codechef.com/wiki/tutorial-dynamic-programming

 类似资料:
  • 我试图通过记忆来解决“计数变化”的问题。 考虑下面的问题:我们可以用多少种不同的方式来换取1美元,半价、四分之一、二分硬币、五分硬币和五分硬币?更一般地说,我们可以编写一个函数来计算使用任何一组货币面额改变任何给定金额的方法的数量吗? 以及递归的直观解决方案。 使用n种硬币改变a的数量的方法数 除第一种硬币外,其他所有硬币都可以换成硬币的方法,加上 使用所有n种硬币改变较小数量a-d的方法的数量,

  • 给定一个值N,如果我们想换N美分,并且我们有无限量的S={S1,S2,…,Sm}值的硬币,我们可以用多少种方式来换?硬币的顺序无关紧要。 例如,对于N=4和S={1,2,3},有四种解:{1,1,1,1},{1,1,2},{2,2},{1,3}。所以输出应该是4。对于N=10和S={2,5,3,6},有五个解:{2,2,2,2},{2,2,3,3},{2,2,6},{2,3,5}和{5,5}。所以

  • 问题内容: 我最近一直在研究Python中的Euler项目问题​​。我对Python相当陌生,但作为一名程序员还是有点陌生​​。 无论如何,我遇到了与速度相关的问题,为问题5编写了解决方案。问题是, “ 2520是可以除以1到10的每个数字而没有任何余数的最小数字。什么是可以被1到20的所有数字平均除的最小正数? 我已经检查了一些,但还没有找到关于此问题的任何有关Python的信息。有一些完整的脚

  • 本文向大家介绍CSS3 动画卡顿性能优化的完美解决方案,包括了CSS3 动画卡顿性能优化的完美解决方案的使用技巧和注意事项,需要的朋友参考一下 为什么会卡顿? 有一个前提必须要提,前端开发者们都知道,浏览器是单线程运行的。但是我们要明确以下几个概念:单线程,主线程和合成线程。 虽然说浏览器执行js是单线程执行(注意,是执行,并不是说浏览器只有1个线程,而是运行时,runing),但实际上浏览器的2

  • 本文向大家介绍MySQL root密码忘记后更优雅的解决方法,包括了MySQL root密码忘记后更优雅的解决方法的使用技巧和注意事项,需要的朋友参考一下 前言 一直以来,对于MySQL root密码的忘记,以为只有一种解法-skip-grant-tables。 问了下群里的大咖,第一反应也是skip-grant-tables。通过搜索引擎简单搜索了下,无论是百度,抑或Google,只要是用中文搜

  • 本文向大家介绍PHP优化教程之解决嵌套问题,包括了PHP优化教程之解决嵌套问题的使用技巧和注意事项,需要的朋友参考一下 在开发过程中,我们经常遇到一对多的场景, 例如:查询订单列表,并且展示订单详情商品、数量数据 思路0:传统做法 a. 查询订单列表 b. 遍历订单详情  分析:查询SQL次数为:N+1(N为订单个数),这样频繁请求数据库,影响效率  优化:减少频繁请求数据库 思路1: a. 查询