这周先是huffman code,这东西是一种对数据进行二进制编码的方式,这样子编码可以压缩空间,算是一种压缩算法。比如一串数据里只有a,b,c,d四个字节,一般可能会觉得就00,01,10,11来指代这四个了,然而这里可能a出现的概率超过60%,其余三个都是百分之十几,那么像0,10,110,111这种编码就更好一些。构造赫夫曼编码的方式算是一种贪心算法,实际上是一个构造二叉树的过程,实际就是先找出出现概率最低的两个点,把它们作为最底层的叶子,然后合并它们的概率,再把它们当做一个点与其他点比较,重复这一过程。实际上我隐约记得离散数学里面好像讲过类似的东西,不过当时是完全不知道这是用来干啥的。
然后是dynamic programming,这是一种算法思想,和二分法或者贪心算法对应的,他基本是一个求最优解的方法,通常涉及到1.搞清楚一个最优解的结构特征。2.以这个结构特征制定方案,递归这个方案。3.求最优解的值,通常是bottom-up的求以避免重复计算。其实挺抽象的,不是太好理解。需要结合具体例子来理解。
光头哥讲的dynamic programming的栗子是一个“求一个直线图的不相临点(每个点都带一个权值)的最大权值之和”的问题。我最开始还以为他说的不相邻的点只能是两个点,想了半天都没想明白他的算法是干啥的,后来才发现原来是所有可能的不相邻点都算在里面的。。。这里具体算法就是:把问题分为两种可能性,一种的最优点集是包括最后一个结点(是指这个一串直线排列的图的最右边的结点),那么倒数第二个结点就不包括,那就对排除最右两个结点的图递归求解;另一种是不包括最后一个结点,那么对除最后一个点的图递归求解。最后比较这两种可能性得出的结果哪个更大,就选取哪个。基本上肯定是一个结果有最后一个点,一个没有,就是按这个区分的。
不过这样的解法,是up-bottom,就有很多重复求值,实际上还是brutal的。优化的办法是把它颠倒过来变成bottom-up,从左向右开始求,先求最左边0个结点和1个结点的最大权值之和,然后向右推进,这样相当于是cach了每一步的结果用于下一步的计算的,就快了很多,只有O(n)了。
当然这样也只能求出最大权值之和,后面还有进一步求出具体的点集的方法。是要在上一步基础之上,先cach了每一步的结果,然后再从右向左判断最开始讲的那两种可能是实际是哪种(就是比较两种可能性的权值之和的大小),然后判断每一步的结点(最开始是最右边的)在不在点集之内。
说实话这算法感觉。。。真的很难。而且过于具体了,感觉不是特别有普适性,学了之后对dynamic programming好像理解也没有更深入(-_-||),总感觉最近光头哥讲的东西越来越变态了。。。
另一门课开始啦——duke的sql,过两天deadline,先上完第一周的,正好换换脑子~
原文地址:https://www.cnblogs.com/dynasty919/p/8495486.html