在網上看到別人ACM學習的心得,轉載過來,源地址不記得了,當時是百度的。內容如下:
網絡上流傳的答案有很多,估計提問者也曾經去網上搜過。所以根據自己微薄的經驗提點看法。
我ACM初期是訓練編碼能力,以水題為主(就是沒有任何算法,自己靠動腦筋能夠實現的),這種題目特點是麻煩,但是不難,30-50道題目就可以了。
然后可以接觸一下基礎的算法,我感覺搜索方向的比較不錯,可以解決很多問題,深搜,廣搜,然后各種剪枝能力的鍛煉。
搜索感覺不錯了就可以去看看貪心,圖論,和動態規划方向的了。圖論有最短路徑,最小生成樹,網絡流,拓撲排序等等很多,動態規划先去書上看經典例子,最長公共子序列等。各種變形的題目。
數學是ACM中極具殺傷力的武器,我一向很羡慕數學好的隊友,精力有限自己數學方面的算法只能說入門。這方面經典的數論,組合數學方面的比較多,計算幾何是很重要的,經典模型要熟悉,最近點對,二維三維,凸包以及各種應用。
數據結構方面的就比較多了,基礎的堆,棧,隊列,並查集,二叉查找樹,紅黑樹,trie樹,hash表等等。 用C++參賽的話STL要熟悉,有時候很有幫助,里面的queue,list,map,stack等。
ACM到后來算法就成了工具,不斷的靠自己意淫一個新的解法來解決問題是最開心的事情了。我們學校ACM一直是一屆帶一屆的,老師只提供經濟上的援助,上面的內容是我在大三當隊長時教給大一的新隊員的入門內容,再深的就靠每個人自己發掘了。
我年輕的時候也覺得ACM考察的是算法和coding
年紀大了以后,我明白了,ACM考察的其實是YY
有算法的題都是秒殺題,
難題都是YY一個方法,或是做一個畸形的變化轉成一個有固定解的模型
一位高手對我的建議:
一般要做到50行以內的程序不用調試、100行以內的二分鍾內調試成功.acm主要是考算法的,主要時間是花在思考算法上,不是花在寫程序與debug上。
下面給個計划你練練:
第一階段:
練經典常用算法,下面的每個算法給我打上十到二十遍,同時自己精簡代碼,因為太常用,所以要練到寫時不用想,10-15分鍾內打完,甚至關掉顯示器都可以把程序打出來.
1.最短路(Floyd、Dijstra、BellmanFord)
2.最小生成樹(先寫個prim,kruscal要用並查集,不好寫)
3.大數(高精度)加減乘除
4.二分查找. (代碼可在五行以內)
5.叉乘、判線段相交、然后寫個凸包.
6.BFS、DFS,同時熟練hash表(要熟,要靈活,代碼要簡)
7.數學上的有:輾轉相除(兩行內),線段交點、多角形面積公式.
8. 調用系統的qsort, 技巧很多,慢慢掌握.
9. 任意進制間的轉換
第二階段:
練習復雜一點,但也較常用的算法。如:
1. 二分圖匹配(匈牙利),最小路徑覆蓋
2. 網絡流,最小費用流。
3. 線段樹.
4. 並查集。
5. 熟悉動態規划的各個典型:LCS、最長遞增子串、三角剖分、記憶化dp
6.博弈類算法。博弈樹,二進制法等。
7.最大團,最大獨立集。
8.判斷點在多邊形內。
9. 差分約束系統.
10. 雙向廣度搜索、A*算法,最小耗散優先.
第三階段:
前兩個階段是打基礎,第三階段是鍛煉在比賽中可以快速建立模型、想新算法
。這就要平時多做做綜合的題型了。
1. 把oibh上的論文看看(大概幾百篇的,我只看了一點點,呵呵)。
2. 平時掃掃zoj上的難題啦,別老做那些不用想的題.(中大acm的版主經常說我挑簡單的來做:-P )
3. 多參加網上的比賽,感受一下比賽的氣氛,評估自己的實力.
4. 一道題不要過了就算,問一下人,有更好的算法也打一下。
5. 做過的題要記好
邏輯類:枚舉、貪心、動態規划、深搜廣搜
結構類:棧、並查集、堆、樹、拓撲圖、圖論
幾何類:凸包
公式類:Fibonacci,排列組合,概率
幾何類的小算法很多,比如求點線關系;還有線性方程組、最大最小流;還有一些特定的算法:最短路徑、排序等。
我感覺最其中重要的是搜索,搜索可以對大部分問題提供通解,但會有效率問題,於是有雙向廣搜、A星搜索等等。在現實應用中,我覺得相對其他一些來講,搜索也是比較有用的。