前端学习算法1 :老虎和羊,吃不吃问题(动态规划入门)

栏目: 编程工具 · 发布时间: 5年前

内容简介:撇开什么是动态规划不谈,我们先来看看题干:有500只老虎,1只羊,一片草原。老虎和羊,都可以吃草活着,对,这个题中的老虎可以吃草。老虎呢,也能吃羊,不允许很多只老虎一起吃羊,只允许一只老虎吃一只羊,并且,吃完羊之后,这个老虎就会变成羊。那么问,老虎会不会吃羊? 提示:老虎很聪明,每只老虎都很聪明。不吃啊,我堂堂威风老虎,干嘛要变成羊?并且变成羊之后,就该被欺负了
前端学习算法1 :老虎和羊,吃不吃问题(动态规划入门)

撇开什么是动态规划不谈,我们先来看看题干:

有500只老虎,1只羊,一片草原。老虎和羊,都可以吃草活着,对,这个题中的老虎可以吃草。老虎呢,也能吃羊,不允许很多只老虎一起吃羊,只允许一只老虎吃一只羊,并且,吃完羊之后,这个老虎就会变成羊。那么问,老虎会不会吃羊? 提示:老虎很聪明,每只老虎都很聪明。

小A回答

不吃啊,我堂堂威风老虎,干嘛要变成羊?并且变成羊之后,就该被欺负了

老师说

你坐下

小B回答

吃,因为羊肉好吃

老师说

你坐下

小C回答

不吃,羊那么可爱,吃了干嘛,不吃还能多个小伙伴

小M回答

不吃! 要保护生态平衡!

老师说

这题我能不能撤回?

不开玩笑了,答案在下面揭晓,为了不使得一打开页面就看到答案,我加些空格。

10

9

8

7

6

5

4

3

2

1

公布答案:不吃。为什么呢?因为老虎很聪明啊。WTF,这是什么理由?不急不急,看看下面的解释,(先插播一个广告,就是本人非常喜欢的游戏‘逆转裁判’,文字游戏,结局通常是大逆转,太赞。)

无从下手之际,不妨逆转一下思维,直接想500这个数字,怎么也不具有什么代表性,要是能联想起大学时候的数学归纳法,就好办多了。数学归纳法通常用来证明一些看起来就不用证明的东西,无从下手的时候,就找特殊情况,比如无穷小的时候满足,无穷大的时候满足,然后再证明个有代表性的一般特例满足就好了。

那么我们也从特殊情况入手

  1. 现在只有 1 老虎,1 羊,那么这只羊会被吃吗?

肯定被吃了,老虎吃了羊后,变成羊,也不会有生命危险了。老虎很聪明,干嘛不吃。

  1. 现在只有 2 老虎,1 羊,那么这只羊会被吃吗?

不会吃。这两只老虎都很聪明,吃了后自己变成了羊,就会被另一只老虎吃掉自己。

  1. 现在只有 3 老虎,1 羊,那么这只羊会被吃吗?

吃啊,吃! 反正吃完后,变成上面的情况后没有老虎敢吃我了,我得体验体验羊肉。

  1. 现在只有 4 老虎,1 羊,那么这只羊会被吃吗?

不吃,吃了后变成上面情况后,自己变成了羊,该被吃掉了。

  1. 现在只有 5 老虎,1 羊,那么这只羊会被吃吗?

吃啊,吃! 反正吃完后,变成上面的情况后没有老虎敢吃我了,我得体验体验羊肉。

  1. 现在只有 6 老虎,1 羊,那么这只羊会被吃吗?

不吃,吃了后变成上面情况后,自己变成了羊,该被吃掉了。

是不是规律已经出来了? 前提不是说了吗,每个老虎都很聪明,500是什么数?是偶数,那么是不会吃的。

动态规划 Dynamic Programming

动态规划意思就是说,大事化小,小事化了。术语的话,包含三个, 最优子结构边界状态转移公式 ,举一个最简单的例子,能更好的理解这三个术语

楼梯台阶有12阶,一步只能走1阶或者2阶,那么,请问走完楼梯有多少走法?

  1. 走到最后一个台阶的前一个情况,只能有两种吧,就是从第11台阶走一步上来,或者从10台阶走两步上来,那么不管有多少走法走到了11阶假设是X种走法吧,假设是Y种走法走到了10阶,那么,走到12阶的走法一定是X+Y,这个是成立的吧。这就是 最优子结构
  2. 那什么是 边界 呢?本例子中,走到第一个台阶,就一种走法吧,没有台阶,那就0种走法吧,走到第二个台阶,也就2种走法,其实这就是边界了。
  3. 那么 状态转移公式 就水到渠成了,F(n) = F(n-1) + F(n-2)

别说话,看代码

function fun(n) {
  if (n < 0){
	return 0
  }
  if (n === 1){
	return 1
  }
  if (n === 2){
	return 2
  }
  return fun(n-1) + fun(n-2)
}
console.log('12台阶的走法 :' + fun(12) )
console.log('11台阶的走法 :' + fun(11) )
console.log('10台阶的走法 :' + fun(10) )
console.log('9台阶的走法 :' + fun(9) )
console.log('8台阶的走法 :' + fun(8) )
console.log('7台阶的走法 :' + fun(7) )
console.log('6台阶的走法 :' + fun(6) )
console.log('5台阶的走法 :' + fun(5) )
console.log('4台阶的走法 :' + fun(4) )
console.log('3台阶的走法 :' + fun(3) )
console.log('2台阶的走法 :' + fun(2) )
console.log('1台阶的走法 :' + fun(1) )
复制代码

运行结果如下

前端学习算法1 :老虎和羊,吃不吃问题(动态规划入门)

其实上面代码是存在问题的,有很多重复的计算。不妨把n限定小一些来看 f(4) = f(3) + f(2),而f(3) = f(2) + f(1),f(2)就是重复计算了。那么代码如何进行优化一翻?

看到上面打印的结果,其实也能发现出规律来,就是3的结果,只依赖1和2,那4的结果有只依赖2和3,而1,2的结果又是显而易见的,那么我们可否逆转一下思维,从下而上计算呢?于是代码如下改造,也就是 真正的动态规划实现

function fun(n) {
  if (n < 0){
	return 0
  }
  if (n === 1){
	return 1
  }
  if (n === 2){
	return 2
  }
  var a = 1
  var b = 2
  var temp = 0
  for(var i = 3; i <= n; i++){
	temp = a + b
	a=b
	b=temp
  }
  return temp
}
console.log( '优化版' )
console.log('12台阶的走法 :' + fun(12) )
console.log('11台阶的走法 :' + fun(11) )
console.log('10台阶的走法 :' + fun(10) )
console.log('9台阶的走法 :' + fun(9) )
console.log('8台阶的走法 :' + fun(8) )
console.log('7台阶的走法 :' + fun(7) )
console.log('6台阶的走法 :' + fun(6) )
console.log('5台阶的走法 :' + fun(5) )
console.log('4台阶的走法 :' + fun(4) )
console.log('3台阶的走法 :' + fun(3) )
console.log('2台阶的走法 :' + fun(2) )
console.log('1台阶的走法 :' + fun(1) )
复制代码

运行结果和之前的相同,如下

前端学习算法1 :老虎和羊,吃不吃问题(动态规划入门)

(其实这也只是动态规划入门,后续会有进阶题目。其实也没啥人看,只是写给自己记录一下而已)


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法设计与分析

算法设计与分析

张德富 / 2009-8 / 36.00元

《算法设计与分析》主要取材于算法设计与分析领域的经典内容,并介绍了算法设计的发展趋势。内容主要包括非常经典的算法设计技术,例如递归与分治、动态规划、贪心、回溯、分支限界、图算法,也包括了一些高级的算法设计主题,例如网络流和匹配、启发式搜索、线性规划、数论以及计算几何。在算法分析方面,介绍了概率分析以及最新的分摊分析和实验分析方法。在算法的理论方面,介绍了问题的下界、算法的正确性证明以及NP完全理论......一起来看看 《算法设计与分析》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具