动态规划-走楼梯

题目:有楼梯n阶,从下往上走,每一步只能跨1阶或者2阶,问总共有多少种不同走法

比如,每次走1级台阶,一共走10步。我们可以简写成 1,1,1,1,1,1,1,1,1,1;

再比如,每次走2级台阶,一共走5步。我们可以简写成 2,2,2,2,2。

解答:

—————————————-step.go———————————————

package dynamicprograming

// 思路:设f(x)为走到第x阶可能的情况,则最后踏上第n阶的前一步有两种情况,n-1 到 n,或者n-2 到 n,也就是f(n)=f(n-1)+f(n-2)
// 又有f(1)=1,f(2)=2 (1+1和2两种情况)

// 递归方式,时间复杂度 o(2^n)
func f0(n int) int {
   if n < 1 {
      return 0
   }
   if n == 1 || n == 2 {
      return n
   }
   return f0(n-1) + f0(n-2)
}

// 由于f0的递归方式中,计算f(n-1)时,f(1)...f(n-2)都已经计算过了,再次计算f(n-2)...f(1)时会重复计算,因此把这些值保存起来避免重复
// 备忘录递归 时间复杂度 o(n),空间复杂度o(n)
func f1(n int, m map[int]int) (ret int) {
   if n < 1 {
      return 0
   }
   if n == 1 || n == 2 {
      return n
   }
   ret, exists := m[n]
   if !exists {
      ret = f1(n-1, m) + f1(n-2, m)
      m[n] = ret
   }
   return ret
}

// f1计算时发现,计算f(n)只要知道f(n-2)和f(n-1)即可,n从1遍历到n,会计算所有的f(1)到f(n-1),
// 因此依次计算f(1)到f(n-1),并由最后两个值f(n-2),f(n-1)推出f(n)即可
// 动态规划 时间复杂度 o(n),空间复杂度o(1)
func f2(n int) int {
   if n < 1 {
      return 0
   }
   if n == 1 || n == 2 {
      return n
   }
   a, b, temp := 1, 2, 0

   for i := 3; i < n+1; i++ {
      temp = a + b
      a = b
      b = temp
   }
   return temp
}

————————————–step_test.go————————————————–

package dynamicprograming

import (
   "testing"
   "fmt"
   "time"
)
var n=30
func TestF0(t *testing.T) {
   start:=time.Now().UnixNano()
   defer func() {
      fmt.Println("递归耗时",time.Now().UnixNano()-start)
   }()
   fmt.Println(f0(n))
}
func TestF1(t *testing.T) {
   start:=time.Now().UnixNano()
   defer func() {
      fmt.Println("备忘录递归耗时",time.Now().UnixNano()-start)
   }()
   m:=make(map[int]int,n)
   fmt.Println(f1(n,m))
}
func TestF2(t *testing.T) {
   start:=time.Now().UnixNano()
   defer func() {
      fmt.Println("动态规划耗时",time.Now().UnixNano()-start)
   }()
   fmt.Println(f2(n))
}

    原文作者:动态规划
    原文地址: https://blog.csdn.net/luopotaotao/article/details/79348651
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞