ACM课程总结

ACM课程总结
转眼间,一学期的ACM的学习就告一段落了。在这一个学期的学习过程中虽然有时候因为一道题的AC不了经常睡不着觉,也有时候因为打比赛打到半夜第二天上课没精神,但是总的来说我还是收获了很多。在这之前我有好多事情没能坚持到最后,但是在这学期的学习中,我坚持每天如果没有特殊情况至少做一道VJ的题目,坚持每个周固定时间写博客,坚持不错过每一场CF的比赛,所以对于我来说和学习那些C++的知识相比我更加高兴的是我养成了坚持的习惯。所以我非常庆幸有费老师这样负责任的老师,如果没有他几乎每节课之前对我们的提醒和激励,我可能不会走到最后。
我最早接触到ACM还是那天晚上自习的时候大二大三的学长学姐来自习室给我们讲关于ACM的有关问题,从那时候我就坚定了学习ACM的信念。之后我参加了学长学姐们组织的有关ACM算法的培训班,那时候有些知识特别是STL的有关内容听得不是很明白,所以我想过放弃,但是那次ACM的新生赛让我感受到了打比赛的乐趣。由于那场比赛和篮球队的训练冲突,所以我只打了一个多小时AC了4道题,感觉挺后悔的吧,现在的我可能会选择和篮球队请假然后继续比赛争取更好的名次。之后大一上学期的选课时虽然之前听学长学姐们说费老师的挂科率很高但是我还是毫不犹豫的选择了ACM这门课。
这个学期我先后接触了递归,二分,贪心,动态规划等知识,又学习了像STL这类的辅助工具,虽然有些东西还没有完全学明白,但是总体来说感觉收获还是挺大的。最开始的时候可能是第一次做英语题干的题目,对于题目的理解和题意的把握有了很大的问题,有些题目是通过一些翻译软件解决的,还有些实在不会题直接从CSDN上找的题解,但是费老师在课上提醒我们不能使用翻译软件,因为有些内容可能翻译的不完全准确,可能会影响题目的解决,然后就是尽量不要依赖题解,虽然题解能很快的告诉你解题的思路,但是毕竟不是自己想出来的,这对于锻炼自己的思维有很大的削弱作用。所以我开始尝试不依靠任何东西自己解决,虽然每道题花费的时间可能很长,但是我感觉到了AC之后平常没有的快乐。然后就是在贪心和动态规划的学习中我遇到了很大的问题,之前听费老师说学长学姐们会一道题两三天不能解决,之前我还不太相信,但是自从接触到了这两块内容,感觉做题的速度真的大不如前,有时候晚上睡不着的时候也是一直想着这道题,印象最深刻的是之前做贪心的一道题时两天没有做出来,第二天凌晨突然有点感觉了,然后爬起来把这道题做了出来,感觉真是挺高兴的。
大约是第八九周的时候我开始打了CF的比赛, 一开始第一场对比赛的出题形式不是很适应,dive 3的比赛只打对了两道题,扣了100多分,然后我听从了学长的建议第二天看了第二题和第三题的题解,大概的了解了CF的出题形式,后面dive 3基本上能出3到5道题,然后dive 2基本上2道题,但是我觉得我的发挥还是不是很稳定,就像昨天晚上的Education比赛我只出了一道题,因为第二道题没有看懂所以直接看了第三道题,但是第三道题因为脑子比较混乱所以做了一个多小时也没有做出来有点可惜。CF的比赛我前几场每场比赛都能参加并且第二天看题解,但是大约达到十场的时候感觉稍微有点累了,打比赛的欲望也没有那么强烈了,就停了两场。接着打比赛的时候发现没有之前那种感觉了,说明打这种比赛特别需要手感。然后之后打了牛客网的一场比赛,出了四道题,有一道以是关于unsigned long long的问题,因为没有记清楚这种内容所以很可惜没有做出来。
下面我大致总结一下这学期学习过的内容,以便之后忘记的时候看看
1.递归算法
递归(Recursion)是指在函数的定义中使用函数自身的方法,然后再问题最简单的情况处结束递归。
想要做好递归,要记住三步:
1、明确递归终止条件;
2、给出递归终止时的处理办法;
3、提取重复的逻辑,缩小问题规模。
2.贪心算法
贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
解题的一般步骤是:
1.建立数学模型来描述问题;
2.把求解的问题分成若干个子问题;
3.对每一子问题求解,得到子问题的局部最优解;
4.把子问题的局部最优解合成原来问题的一个解。
3.动态规划
动态规划程序设计是解最优化问题的一种途径,一种方法,而不是一种特殊的算法,他针对不同类型的问题存在不同的解题方法。
下面是解决动态规划的一般步骤:
1、判断问题是否具有最优子结构性质,若不具备则不能用动态规划。
2、把问题分成若干个子问题(分阶段)。
3、建立状态转移方程(递推公式)。
4、找出边界条件。
5、将已知边界值带入方程。
6、递推求解。
4.背包
背包,它主要分为01背包,完全背包和多重背包。
1、01背包:它是给定N件重量为m[i]、价值为w[i]的物品和承重为V的背包,求在背包承重范围内接受物品的最大价值。他的特点是每种物品只有一件,只能选择放或者不放。
转移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i])。
还可以将其压缩到一维状态:
for(int i=1->n)
for(int j=v->1)
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
2、完全背包:它也是给定N种重量为m[i]、价值为w[i]的物品和承重为V的背包,求在背包承重范围内接受物品的最大价值。它的特点是每种物品可以取若干件。
转移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-m[i]]+w[i])。
借用01背包的思想,本次使用的转移方程也是只涉及到i-1的纵向级别。但与上面不同的是,此次考虑的对象是dp[i][j-v[i]],所以我们必须让体积由前向后循环:
for(int i=1->n)
for(int j=1->v)
dp[j]=max(dp[j],dp[j-v[i]]+w[i])。
3、多重背包:它的问题的思路跟完全背包的思路非常类似,只是k的取值是有限制的,但是每件物品的数量是有限制的。
转移方程: dp[i][v] = max{dp[i - 1][v - k * c[i]] + w[i] | 0 <=k <= n[i]}
其中c[i]是物品的数量,和完全背包的不同支出在于完全背包可以取无数件,而多重背包给定了最多能取的数量。这样也是三个循环,分别是背包容量,物品个数和物品种类。
5.二分和三分
二分:
(1)将所要求的结果当做二分查找的对象,确定[l,r][l,r][l,r]区间,
(2)确定某个mid=(l+r)>>1mid=(l+r)>>1mid=(l+r)>>1是否是一个可行解,根据是否可行解更新l,rl,rl,r的值,直到循环结束。
三分:类似二分的定义Left和Right
mid = (Left + Right) / 2
midmid = (mid + Right) / 2;
如果mid靠近极值点,则Right =midmid;
否则(即midmid靠近极值点),则Left = mid;
6.数论
感觉数论这块内容学的非常不好,以后要经常性的回顾一下这些内容。下面这个博客网址包含着一些常用的数论知识。
https://blog.csdn.net/DreamPoem/article/details/79285074
最后我还是想感谢费老师这个学期的教导,您对我来说教我的不仅仅是知识层面的,更重要的是教会了我坚持,您让我们每周坚持写博客,总结这周的学习效果,您每节课几乎都提醒我们坚持的重要性,所以我非常幸运能有您这样一位老师。最后我想用您说过的一句话作为总结:生死看淡,不服就干!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值