程序设计与算法(二)算法基础,讲授基本的算法。前置课程为程序设计入门,后续是C++ OOP,夹在中间的这门课难度不高,使用的工具也比较基础,这让PAT甲级满分的我在听课时甚至有些尴尬。不过好在课程中使用的都是C++语言,相较于以前学的数据结构课程,这一点让我无比温馨。算法
“本课程中一部分的例题,难度与中学信息学奥赛NOIP提升组的较难题至关,也和ACM国际大学生程序设计竞赛中的中等题至关。”ACM什么的我不关心,可是即将参加CCF-S的我怀疑例题是否达到NOIP的难度,由于听课过程当中几乎没有难以理解的地方,甚至不少都是快进跳过的,而练习题也比较轻松解决了。然而NOIP题我看一眼就不会作。编程
为了考试,我得继续学算法,目前定为算法设计与分析之入门篇、算法设计与分析之进阶篇和《算法导论》。在开始新的课程以前,我先把刚学完的课程总结一下。数组
之前一直以为枚举就是把全部可能值穷举一遍,是很是耗时的。然而不少状况下只须要对几个变量进行枚举,其余的能够由此推导出来,这样枚举量就能够指数降低了。事实上不多有题目会容许所有枚举而不超时。数据结构
递归自己没什么好讲的,从最初学编程就开始接触了。工具
Boolean Expression这道题为我未来写汇编器提供了一点启发。学习
简单的整数划分问题,输入为[1,50]的整数,输出也是一个整数,让我想到这个问题彻底能够编译期完成,而C++模板原本就是擅长递归的。有机会专门写一篇模板元编程,这道题就是一个很好的应用。测试
二分算法已经在搜索等应用中写了好久了,但它在题目中的用法对我来讲是新知识。若是一个输出量与输入量是单调的关系,就能够考虑使用二分算法肯定输出量受约束时输入量的极值。优化
彻底不记得分治讲了什么,赶忙回去翻了翻讲义。例题和练习都是“输出前k大的数”和“求排列的逆序数”。我感受这两个算法都是比较难想的,只有输入数据规模提示了才能明确优化的目标,即O(n)或O(nlogn)。设计
一个很经常使用的结论是,若是分治后合并的过程的时间复杂度是O(n),那么整体时间复杂度是O(nlogn)。反过来说,若是能猜出一道题要求写O(nlogn)的算法,而且能够用分治解决,合并的过程不能超过O(n)。排序
以前在PAT作题的时候,还没学DP,就开始作DP的题了。看别人的博文学了01背包,也利用动规的方法作对过题目。这回是系统的学习了。
课程中讲的递归化动规的方法我不是很明白,状态转移方程比较好理解,只是具体问题中如何肯定变量和转移方程,须要沉下心来思考。有时候内存会超限,能够考虑滚动数组。
如今还不怎么熟练,一小时一题的速度确定是不够的,还得多作题。以及国庆期间作到这里的时候POJ崩了,出现了从没见过的validator error。
学数据结构的时候,DFS好像没有什么存在感,拓扑排序、Dijkstra等都是相似BFS的算法,只记得有一些题目DFS和并查集都能解决。
而实际上DFS的能力还挺强的,听说几乎全部的图问题均可以用DFS解决。可是,DFS中须要保存路径,而且不保证第一个解是最优解。为了提升效率,能够加入可行性剪枝与最优性剪枝。
一些问题中变量表明着状态,状态之间的转移与变量之间的关系有关,这样的问题就能够等效为图,其中状态为顶点,关系为边,能够用图的方法来解决。
第一次见识到算法的证实如此繁琐。对于一些题目,贪心的取法比较复杂,不容易想到,尤为是最后一题田忌赛马,POJ还不给测试数据。后来去查了答案才会作。
用一句话来总结这门课:原来之前学过的东西还能够这么用。