您好,欢迎来电子发烧友网! ,新用户?[免费注册]

您的位置:电子发烧友网>源码下载>通讯/手机编程>

Swift算法实例分析之动态规划

大小:0.5 MB 人气: 2017-09-25 需要积分:1

  今天要讲的动态规划,其面对的问题通常是无法一蹴而就,需要把复杂的问题分解成简单具体的小问题,然后通过求解简单问题,去推出复杂问题的最终解。

  形象的理解就是为了推倒一系列纸牌中的第100张纸牌,那么我们就要先推倒第1张,再依靠多米诺骨牌效应,去推倒第100张。

  实例讲解

  斐波拉契数列是这样一个数列:1, 1, 2, 3, 5, 8, 。。. 除了第一个和第二个数字为1以外,其他数字都为之前两个数字之和。现在要求第100个数字是多少。

  这道题目乍一看是一个数学题,那么要求第100个数字,很简单,一个个数字算下去就是了。假设F(n)表示第n个斐波拉契数列的数字,那么我们易得公式F(n) = F(n - 1) + F(n - 2),n 》= 2,下面就是体力活。当然这道题转化成代码也不是很难,最粗暴的解法如下:

  func Fib() -》 Int {

  var prev = 0

  var curr = 1

  for _ in 1 。。《 100 {

  var temp = curr

  curr = prev + curr

  prev = temp

  }

  return curr

  }

  用动态规划怎么写呢?首先要明白动态规划有以下几个专有名词:

  1. 初始状态,即此问题的最简单子问题的解。在斐波拉契数列里,最简单的问题是,一开始给定的第一个数和第二个数是几?自然我们可以得出是1

  2. 状态转移方程,即第n个问题的解和之前的 n - m 个问题解的关系。在这道题目里,我们已经有了状态转移方程F(n) = F(n - 1) + F(n - 2)

  所以这题要求F(100),那我们只要知道F(99)和F(98)就行了;想知道F(99),我们只要知道F(98)和F(97)就行了;想要知道F(98),我们需要知道F(97)和F(96)。。。,以此类推,我们最后只要知道F(2)和F(1)的值,就可以推出F(100)。而F(2)和F(1)正是我们所谓的初始状态,即 F(2) = 1,F(1) =1。所以代码如下:

  func Fib(n: Int) -》 Int {

  // 定义初始状态

  guard n 》 0 else {

  return 0

  }

  if n == 1 || n == 2 {

  return 1

  }

  // 调用状态转移方程

  return Fib(n - 1) + Fib(n - 2)

  }

  print(Fib(100))

非常好我支持^.^

(0) 0%

不好我反对

(0) 0%

      发表评论

      用户评论
      评价:好评中评差评

      发表评论,获取积分! 请遵守相关规定!