ACM学习心得(5000字)

来源:互联网 发布:算法新解刘新宇pdf 编辑:程序博客网 时间:2024/06/05 19:38

ACM学习心得

姓名:  邓华伟          学号: 20163940           专业班级:计算机1

   转眼之间,一个学期就这么过去了,ACM课程也圆满的落下了帷幕,经过这一学期的学习,感觉自己有了很大的成长和巨大的收获,自己也对c++语言有了重新的一个认识和定义,原来并不是只有我们教科书上学习的那么简单,,这让我想起了一句话,外面的世界很精彩!如果不学ACM,恐怕我觉得会和大多数同学一样,在对c++编程上一窍不通!下面,我来介绍一下本人学习ACM课程与设计的学习心得!

   我最早了解或者说听说ACM的时候,是大二的一个学长来我们计算机专业做宣传时听说的,当时听他介绍了ACM就对ACM有较深的印象和较大的兴趣,记得当时就紧紧跟在他身后问他学好ACM有什么条件吗,一直追着不放,其实真正接触到ACM是在那次我们学校举办的程序设计比赛之后,一开始信心满满的去比赛,结果发现自己除了A+B什么都不会,然后根据老师的推荐,买了《信息学奥数一本通》那本书,开始系统的接触ACM的有关内容了!记得当时自己一直在纠结到底要不要选修ACM这门课程,纠结了好久好久,有很多同学是去蹭课,但是我觉得那样的话自己是没有压迫感的,当然也就会学不好,老实说在大学里全心全意做一件事情是很困难的,但ACM给我们提供了这个平台和这个好机会,所以我决定逼自己一把,于是便选修上了ACM,我很庆幸当时选择了这门课,而没有放弃,否则我觉得这将会是大学里一个非常大的遗憾,自己就不会了解到外面的世界真的很精彩!ACM是自己提前接触到了算法,数据结构等一些的重要内容,这对我以后的发展具有重要的作用!

  我们在寒假的时候就一直在为课程做准备,寒假期间,我们晚上经常会做一些练习赛,老师放一些经典的题目,从cf上摘一些题目,这让自己真正的意识到自己的不足,其他同学在群里讨论问题,然而有些内容我竟然听都没听说过,这时我明白过来,有些同学早就开始接触ACM甚至学习ACM了,而我还仅仅停留在我们教学的课本上所接触的内容,所以意识到,我们比别人起步晚了,学的少了,如果以后再不努力,差距将会越来越大,自己将永远被甩在身后,虽然目前自己的能力和实力和其他同学相比,仍然有很大的不足,但自己总归是在一点点的前进!寒假期间,老师给了我们一些资料来供我们学习,我觉得一个寒假的学习,自己真的提高了不少,最起码一些基本常识知道了一些!我在假期主要学习了STL的一些内容,看了老师推荐的《ACM程序设计》这本书,我觉得给我最大的感触就是,还有这种操作?比如,我们课上学习的冒泡排序等,在STL中仅需要加个algorithm的头文件,然后sort()排序即可!这真的是自己不敢想象的,还有就是vector的认识,它完全可以代替数组,对一些插入删除操作,比数组要方便的好多好多!下面简单介绍一下学习的总结:
   看完《《ACM程序设计基础》》之后,对c++STL(即Standard Template Library,标准模板库又称c++泛型库)有了一定的了解,它在std命名空间中定义了常用的数据结构和算法,对我们平时做题来说,使用起来非常方便。

   从根本上说,STL是一些“容器”的集合,这些“容器”有list, vector,set,map等,STL也是算法和其它一些组件的集合。它们都是c++的重要组成部分。总之,STL提供三种类型的组件:容器,迭代器,算法,它们都支持泛型程序设计标准。

一、容器    

   首先介绍容器,容器主要有两类:顺序容器和关联容器。其中顺序容器有:vector,list,deque,string等,它们是一系列元素的有序集合。关联容器包括:set,multiset,mapmultimap,它包含查找元素的键值。

   1.vector

   vector就是动态数组,vector向量不但能够像数组那样对元素进行随机访问,还能在尾部插入元素,是一种简单高效的容器,完全可以代替数组。Vector存放在一片连续的内存块中,因此它只能向后增长,如果需要在vector的中间插入新元素,则会导致插入位置起后面的所有元素都要往后迁移;另一方面由于它连续存储,因此随机访问元素很方便。

2.string基本字符系列容器

C++STL提供了string基本字符系列容器来处理字符串,它提供了添加、删除、替换、查找和比较等丰富的方法。注意:string容器需要声明头文件"#include<string>".这个对字符串的操作是非常方便的,不再需要指针之类的东西,访问string对象的元素一般使用下标方式随机访问string对象的元素,下标是从0开始计数的,string对象的元素是一个字符(char

当然也可以使用迭代器进行访问,但是string的迭代器一般不用来访问元素,而是对其中的元素进行删除,插入和替换操作的时候作为参数。删除元素:

1erase(位置):删除单个元素;

2erase(位置1,位置2):删除区域内的多个元素,其中,位置用迭代器表。注意,不是下标

求字符串长度:

(1)length();2empty():为空返回1,不为空返回0

3 stack( 栈)和queue(队列)

stack是一种先进后出(FirstInLastOut,FILO)的数据结构,它只有一个出口,只能操作最顶端元素。

queue是一种先进先出(FirstIn First Out, FIFO)的数据结构,从底端加入元素,从顶端取出元素。

4 mapmultimap

所有元素都会根据元素的键值自动排序,map的所有元素都是pairpair的第一个元素被视为键值,第二个元素为实值。map不允许两个元素有相同的键值,但multimap可以。

5优先队列(priority_queue

一个拥有权值观念的queue,自动依照元素的权值排列,权值最高排在前面。缺省情况下,priority_queue是利用一个max_heap完成的

二、迭代器:

迭代器有输入迭代器,输出迭代器,前向迭代器,双向迭代器等。它能够用来遍历标准模板库容器中的部分或全部元素,对我们平时对元素的操作有很大的便利,使用反向迭代器reverse_iterator可以反向遍历集合,输出的结果正好是集合元素的反向排序结果,他需要用到rbegin()rend()两个方法,它们分别给出了反向遍历的开始位置和结束位置。

.算法

算法部分主要由头文件<algorithm>包含,它可以包含比较(compare)、交换(swap)、查找(find)、遍历操作(iterator)、复制(strcpy)、移除(erase)、反转(reverse)、排序(sort)、合并等等,在c++中,由于算法的存在,给程序的编写提供了很大的便利。

  然后开学回来之后,又对专题进行了总结!感觉自己真的收获了好多好多!随后我们学习了递归递推的内容,一开始总感觉像高中的找规律,其实并没有那么简单,递归与递推算是ACM中比较重要的知识点,其难点主要在于对关系式的分析,当你建立起来关系式时,题目就变得轻而易举,难就难在对关系式的分析与寻找,对递推公式的建立上,在运用递推递归解决问题是,一定要仔细分析题目,其中另外重要的一点就是边界(终止)条件的寻找,此问题处理起来较为简单。在运用递推递归时,要灵活运用,有时不需要递归,只需一个for循环即可解决问题,还有就是还可以对数据进行预处理,以及运用前缀和等等,为递推递归解决问题提供了很大的方便。总之还是那句话,寻求大问题与小问题之间相互的联系。

一、递推

递推算法是一种用若干步可重复的简运算(规律)来描述复杂问题的一种方法!即一个问题的求解需一系列的计算,在已知条件和所求问题之间总存在着某种相互联系的关系;如果可以找到前后过程之间的数量关系,能使复杂运算化为若干步重复的简单运算,充分发挥出计算机擅长于重复处理的特点。递推算法的首要问题是得到相邻的数据项间的关系(即递推关系)。把一个复杂的问题的求解,分解成了连续的若干步简单运算。l另外 递推可以分为顺推和逆推,具体的问题要求具体的分析,寻找问题的最优解!

总之一句话:就是将大的问题寻求子问题来解决!

二、递归

程序直接或间接调用自身的编程技巧称为递归算法 Recursion)。直接或间接调用自身的函数称为递归函数。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。

1、递归算法的基本思想:(问题分解)

把一个不能或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的小问题,
最小问题可以直接解决。 

2、递归的关键在于找出递归定义和递归终止条件:

递归定义:使问题向边界条件转化的规则。递归定义必须能使问题越来越简单。 
递归终止条件:也就是所描述问题的最简单情况,它本身不再使用递归的定义。

3、递归算法解题通常有三个步骤:
1)分析问题、寻找递归:找出大规模问题与小规模问题的关系,这样通过递归使问题的规模逐渐变小。
2)设置边界、控制递归:找出停止条件,即算法可解的最小规模问题。
3)设计函数、确定参数:设计函数体中的操作及相关参数。 

4、我认为写好一个递归算法主要需要掌握三个方面:

1 找到其中重复的逻辑。

2 需要控制编辑的条件!

3 就是要寻找恰当的结束条件,不至于使程序为死循环!

  之后又学习了ACM中最难的一部分,动态规划,真的是难到怀疑人生,很多人在这里就停止了ACM的学习之路,认为ACM非常难,我觉得正如费老师所说的,很多人栽在这个坎上,咬牙坚持住,就一定会有所收获的!

1.动态规划是一种解决多阶段决策问题的方法!而不是一种特殊的算法!

2.多阶段决策问题:

   2.1多阶段决策问题:如果一类问题的求解过程可以分为若干个互相联系的阶段,在每一个阶段都需作出决策,并影响到下一个阶段的决策。

   2.2多阶段决策问题,就是要在可以选择的那些策略中间,选取一个最优策略,使在预定的标准下达到最好的效果.

3.最优性原理:

   3.1不论初始状态和第一步决策是什么,余下的决策相对于前一次决策所产生的新状态,构成一个最优决策序列。

   3.2最优决策序列的子序列,一定是局部最优决策子序列。

   3.3包含有非局部最优的决策子序列,一定不是最优决策序列。

4.指导思想:

   4.1在做每一步决策时,列出各种可能的局部解

   4.2依据某种判定条件,舍弃那些肯定不能得到最优解的局部解。

   4.3以每一步都是最优的来保证全局是最优的。

5.动态规划的基本模型:

   5.1动态规划问题具有以下基本特征:

   5.2问题具有多阶段决策的特征。

   5.3每一阶段都有相应的“状态”与之对应,描述状态的量称为“状态变量”。

   5.4每一阶段都面临一个决策,选择不同的决策将会导致下一阶段不同的状态。

   5.5每一阶段的最优解问题可以递归地归结为下一阶段各个可能状态的最优解问题,各子问题与原问题具有完全相同的结构。

6.dp的几个概念:

   6.1阶段:据空间顺序或时间顺序对问题的求解划分阶段。

   6.2状态:描述事物的性质,不同事物有不同的性质,因而用不同的状态来刻画。对问题的求解状态的描述是分阶段的。

   6.3决策:根据题意要求,对每个阶段所做出的某种选择性操作。

   6.4状态转移方程:用数学公式描述与阶段相关的状态间的演变规律。

7.解题步骤:

   7.1判断问题是否具有最优子结构性质,若不具备则不能用动态规划。

   7.2把问题分成若干个子问题(分阶段)。

   7.3建立状态转移方程(递推公式)。

   7.4找出边界条件。

   7.5将已知边界值带入方程。

   7.6递推求解。

   简言之,能用动态和规划解决的问题需要有最优子结构,也就是大问题可以拆成一些小问题,这些小问题和大问题的形式基本是一样的,然后我们在循环中不断更新这些小问题的结果,用数组记录下来,一直到最终的问题时我们直接到数组中取值就可以了。实际上动态规划就是这样子,做题的过程中发现其实子问题很好找的,把问题规模降低子问题就找到了。

最难得其实是状态转移方程,这个一般是挺难找的,我感觉还是从问题的最终目的去考虑方案,比如我们看看到最终的目的有几条路径,这是关键,因为子问题的结构和大问题是一样的。我们只要找到大问题的路径,状态转移方程就找到了。总之,最难找的和最关键的就是状态转移方程!

  走过难关,我们又接触到了背包(01背包,完全背包,多重背包),二分(三分),贪心(关键是贪心标准的选择),以及万能的解题方法搜索(深搜和广搜,注意广搜一般运用队列),然后又学习到了数据结构(树等)的有关内容,再次不再一一列举,数论以及其他内容由于时间紧张我们没有一一学习,虽然如此,但仍然感觉自己收获好多!在这学期中,给我印象最深刻的一件事就是去青岛参加第八届浪潮杯山东省ACM程序设计竞赛,感觉这是一次非常宝贵和难得的经验,虽然只拿得了铜奖,但是感觉自己的付出总算是有了一点回报!这次让我体会到了团队协作的重要性和解决问题的高效性,团队协作思考问题更加全面了,处理问题的方法更加多样化和简洁化,每个人个抒己见,寻找问题的最优解和最简便的方法,对我们编程能力有了很大的提高,同时第一次体会到了大赛的氛围,此次比赛中,有很多的遗憾和做的不错的地方,我觉得最成功的地方就是我们严格按照费老师所说的,像我们这样的水平,紧跟榜单就可以,然后最后一个小时,专门攻克一个问题,不要再三心二意,做会这个题然后再看会那个题,集中精力攻克一道题就可以,其中有道题,就花费了将近两个小时,好在在最后一个小时封榜的时候将那道题AC了,我觉得这是我们最成功的的地方。

  虽然课程结束了,但是我们还有很长的路要走,我想要继续坚持下去走ACM的道路,多刷题,多做题,使自己不断成长和壮大起来,虽然和别人有一定的差距,但我想努力了也就不会后悔了,天道酬勤,人就怕努力,我觉得在以后的日子里,一定继续前行,不忘初心,坚持下去,相信自己一定会成功!

 

 

 

 

原创粉丝点击