一.感想
:
在大一下学期的算法基础学习中,毫无疑问,自己的代码水平以及思维深度都有了显著的提高。虽然刚开始做题的时候会感觉到有些无从下手,有时甚至一道题那过来,就会感到头脑毫无思路,这是很正常的一件事,但是记住一件事:不要回避,回避只会令自己更加懒惰,当你全身心的投入到算法知识的海洋中去的,你会感叹原来“哦,原来三分算法可以用到现实当中无人驾驶汽车拐弯技术中去啊”,“原来最小生成树可以跟某些查询系统结合求最短路径啊”,“嗯,路径压缩能使并查集的操作大大简化”,你会发现acm就像一场游戏一样,做出一道题来后还是很有成就感的。另外,我觉得要注意的一件事就是要注意总结和培养自己独立思考.勇于尝试的能力。1.
所谓的独立思考,就是不要养成做不来就上网搜别人代码的习惯,如果实在做不出来,可以尝试问一下别人思路,然后再尝试自己去实现,等做出来之后再看别人的代码,学习一些好的地方。2.而所谓的敢于尝试,就是不要怕错,编程是一件很特别的事情,他可以在当场验证你的理论的正确性,当你头脑清晰时,你就是国王。所以,不要把错藏在心里,打开电脑自己试下,自然就明了了,也只有这样,你才能从自己完成的每一道题中获得快乐。3.最后就是解题总结了,在这个过程中,你会重新梳理一遍代码过程,做好注释,你会更有收获,不至于几个月后忘得一干二净。
二.学习历程:
首先列一个清单,看看自己到底学会了多少东西,在这一个学期的学习中。简单的贪心算法,贪心与其说是一种算法,倒不如说是一种思想,在寻求最优解的过程中,都在寻求局部的最优解,解这类贪心问题策略关键是分析局部的最优解是否能构造出问题的最终解。简单的动态规划问题:这类题的关键就是就是寻找问题状态转移方程,有时候实在想不出就可以用待定系数法来求出状态转移方程。背包问题。提前学到了数据结构的内容:
STL
中先进先出的栈,先进后出的队列,优先队列,
map
容器等,以及一些函数
size. Empty.pop. Push
的操作。
Sort
函数的使用,调用
sort
排序。打表这种方法。搜索专题:学会了深度优先搜索
DFS
,广度优先搜索
BFS
这两种搜索的基本思想和过程分析。学到了记忆化搜索这种以空间换时间的优化策略,二分查找,三分查找。图算法:目前仅学会了几种方法,并查集的操作解决点集的所需连通数,用
Prim
算法和
kruskal
算法(求边上的权值,额,好像没啥区别)解决最小生成树问题,
bellman-ford
,
spfa
,
dijkstra
来解决单源最短路径问题,松弛技术等。下面详细描述各模块的内容。。
贪心算法
:
1.建立数学模型来描述问题。
2.把求解的问题分成若干个子问题。
3.
对每一子问题求解,得到子问题的局部最优解。
4.
把子问题的解局部最优解合成原来解问题的一个解
贪心算法一般用于以下几种问题:
转化为背包划分,活动时间的安排,数字组合问题但是该算法也存在一些问题:不能保证求得的最后解释最佳的;不能用来求最大或着最小解的问题;只能求满足某些约束条件的可行解的范围。
例如:第一题就是一种活动安排问题,活动安排问题要注意的一个点就是弄清楚题目是串行的还是并行的,找出标准。
模板:
按活动的结束时间升序排序
排序比较因子:
bool cmp(const action &a, const action &b)
{
if (a.f<=b.f) return true;
return false;
}
使用标准模板库函数排序(下标0未用):
sort(a, a+n+1, cmp);
形参数组b用来记录被选中的活动
void GreedySelector(int n, action a[], bool b[])
{
b[1] = true; //第1个活动是必选的
//记录最近一次加入到集合b中的活动
int preEnd = 1;
for(int i=2; i<=n; i++)
if (a[i].s>=a[preEnd].f)
{
b[i] = true;
preEnd = i;
}
}
背包问题:这类题一般分为以性价比或者是用物品的重量的标准衡量。
模板:
struct bag{
int w;
//物品的重量
int v;