算法分析与实践-作业13
读后感
由于参与了我院ACM实验室的缘故,我有幸阅读了《算法竞赛》(进阶指南)这本书。尽管并没有能完全地渗透这一本书,但是还是在这本书上学习一些比较有用的算法。算法可以说是基础,很多问题倘若我们使用暴力的方法去解决,复杂度甚至可以达到O(n!),但是当我们使用了一些算法去优化,复杂度可以降到O(nlogn),这能够极大的节约我们的时间。比如对于一个相同的问题,没使用算法的人跑了一天,而使用算法的人只需要短短的几秒钟,这样的差距是巨大的,同时也可见算法给我们带来了极大的便利。
这本书中关于动态规划的这一部分令我十分敬佩。我一直觉得在算法竞赛中,动态规划是一块非常难的部分,动态规划的题目一般是非常有灵性的。有很多题目你甚至第一时间不能直接想到动态规划,反而会尝试用贪心的思想去解决。我觉得对于动态规划而言,有几个方面的内容是非常重要的。首先就是转移关系式的书写,往往在这一步我们就能卡好久,我们需要联想到当前这一状态,能够从之前的哪几个状态进行转移,如何转移;又或是数组,我们是需要开二维数组、三维数组甚至于四维数组,数组的每一维状态又分别表示什么;初始化问题等等,这些都是动态规划问题的难点。
在这本书中,他讲解了许多不同类型的动态规划,其中斜率优化动态规划我学了好久,所谓斜率优化动态规划,就是根据你自己得出的一条不等式,将所有能够转移的状态放在一个队列中,队头的元素就是我们当前转移的最优状态,然后这个队列需要用到你自己写出来的这个不等式来进行维护,一般来讲,我们需要维护的队列依赖于队列中相邻两个元素之间的某种“比值”。因为这个值对应线性规划的坐标系中的斜率,所以我们称此为斜率优化动态规划。这也可以算是一种线性规划问题。斜率优化动态规划也是极大地扩展了我的眼界。
在之前,我也做过一道题目,题目的大致内容是这样的,给你n个棒子,每根棒子的长度已知,问你有多少种方法使得从这n根棒子中选出3根能够组成三角形。很自然地想法是暴力枚举,但是时间复杂度为O(n3),并且n的范围是1e5,使用这个复杂度明显不能在1秒中跑出结果,后来我搜了一下这道题目的题解,发现这道题目所用到的算法是快速傅里叶变化(FFT),能够将复杂度降到O(nlogn)。也算是学到了不少东西吧!
我觉得算法更多的给予我们的是一种对于题目的思考方向。就好比老师上课讲的,用算法没什么,真正能设计出算法的,那才是厉害的人。读这本书极大地扩展了我的思路,教会我思考问题时,不能单单从一个方面去思考,得时常冒出更加精彩的想法!