Python数据结构与算法分析
Day14
我们昨天学习了找零兑换问题的动态规划解法,今天继续学习动态规划案例分析---博物馆大盗问题。0 1博物馆大盗问题及其递归复习
大盗潜入博物馆,面前有五件宝物,分别有重量和价值,大盗的背包仅能负重20kg,请问如何选择宝物总价值最高?
![30df4dd683646d48fdcbb813f1e96ff9.png](https://i-blog.csdnimg.cn/blog_migrate/10778e72e59588195ce5a0c889c2a159.png)
我们把m(i,w)记为:
前i(1<=i<=5)个宝物中,组合不超过w(1<=w<=20)重量,得到的最大价值m(i,w)应该是m(i-1,w)和m(i-1,w-wi)+vi两者最大值,我们从m(1,1)开始计算到m(5,20)。
![f918851c199ce2b89b6a39888c261d1e.png](https://i-blog.csdnimg.cn/blog_migrate/ed63954f9d47722a71761d44963cffbb.png)
![af890105661f2cf896b6fca8be6507e6.png](https://i-blog.csdnimg.cn/blog_migrate/90da647f5cb4dccd1af6f6b8c33f1321.png)
递归解决博物馆大盗问题代码:
上边我们用动态规划和递归分别解决了博物馆大盗问题,由于递归算法简洁直观,只要递归和记忆化应用得当,也能高效解决这类问题。
递归的学习到这也就告一段落了,我们简单的回顾一下本章内容。
在本章我们研究了几种递归算法,表明了递归是解决某些具有自相似性的复杂问题的有效技术。大家还记得递归算法的三原则?
递归算法必须具备基本结束条件;递归算法必须要减小规模,改变状态,向基本结束条件演进;递归算法必须要调用自身。
在某些情况下,递归可以代替迭代循环;递归算法通常能够跟问题的表达自然契合;递归不总是最合适的算法,有时递归算法会引起巨量的重复计算;函数值缓存可以通过附加存储空间记录中间计算结果来有效减少重复计算;如果一个问题最优解包括规模更小相同问题的最优解,就可以用动态规划来解决了。
递归相关内容到这我们就先告一段落了,下边就要开启排序与查找的相关内容。会给大家介绍2种查找和6种排序的方法,查找有顺序查找和二分查找,排序包括冒泡排序、选择排序、插入排序、希尔排序、归并排序以及快速排序。
查找是是指从元素集合中找到某个特定元素的算法过程,查找过程通常返回True或False,分别表示元素是否存在。
Python提供了运算符in,通过它可以方便地检查元素是否在列表中。
![130b716cb91ffedfbaac048006bc4b34.png](https://i-blog.csdnimg.cn/blog_migrate/991f8f44cf7d2af4cb10098dfbf9f744.png)
尽管写起来很方便,但是必须经过一个深层的处理过程才能获得结果。事实上,搜索算法有意两个单很多种,我们感兴趣的是这些算法的原理及其性能差异。
![a0ffcd424c6c62dbdb8fe832ecc3a94a.gif](https://i-blog.csdnimg.cn/blog_migrate/a9b3b437a16f00b17a6b26432de9fab0.gif)
顺序查找
如果数据项保存在如列表这样的集合中,我们会称这些数据项具有线性或者顺序关系。在Python列表中,这些数据项的存储位置称为下标,这些下标都是有序的整数。通过下标我们就能按照顺序来访问和查找数据项,这种技术称为顺序查找。
要想确定列表中是否存在需要查找的数据项,首先从列表的第一个数据项开始,按照下标增长的顺序逐个对比数据项,如果到最后一个都没有发现要查找的数据项,那么就查找失败。
![a0ffcd424c6c62dbdb8fe832ecc3a94a.gif](https://i-blog.csdnimg.cn/blog_migrate/a9b3b437a16f00b17a6b26432de9fab0.gif)
顺序查找算法分析
要对查找算法进行分析就要确定里边的基本计算步骤。回顾一下第二章算法分析的内容,这种基本计算步骤必须要足够简单,并且在算法中反复执行。在查找算法中,这种基本计算步骤就是进行数据项的比对,当前数据项等于还是不等于要查找的数据项,比对的次数决定了算法复杂度。
在顺序查找算法中,需要假定列表中的数据项并没有按值排列顺序,而是随机放置在列表中的各个位置。也就是说数据项在列表中各处出现的概率相等。数据项是否在列表中,比对的次数是不一样的,如果不在列表中,需要比对所有数据项,比对次数为n;如果数据项在列表中,要比对的次数就复杂了,最好的情况就是第一次就能比对出来,最坏的情况要n次比对。
我们在这里假定列表中数据项是无序的,那如果数据项排了序,顺序查找算法的效率又如何呢?
实际上,我们在有序表Search方法中介绍过顺序查找。当数据项存在时,比对过程与无序表完全相同,不同之处在于数据项不存在时比对可以提前结束。比如我们要查找数据项50,当看到54时就知道后边肯定不存在50就可以提前退出查找。
实际上,算法复杂度仍然是O(n),只是在数据项不存在的时候,有序表的查找能节省一些比对次数,但这并不改变数量级。
顺序查找有序表的情况分析:
![67f64a8148582c6e745d97c7ec95dafe.png](https://i-blog.csdnimg.cn/blog_migrate/69aaf5e7a6f0fb565b7318e016c20189.png)