ACM學習總結

2021-08-02 18:22:10 字數 4739 閱讀 3555

acm總結報告

與acm程式設計這門課的接觸是從大一上學期學校舉辦的面向大一新生的程式設計比賽,當時雖然什麼也不會,只會簡單的c++與c語言,當時學過的最複雜的程式就是氣泡排序了,現在回想起來還真是有趣,只是憑著一點興趣就去參加了這個比賽,現在想來,如果不是那點興趣我也不會接觸到這一門課,當時比寒結束然後幾位學長便在上面給我們介紹了他們 學習歷程,然後留下了qq群的號碼,然後加入qq群,在寒假的期間簡單接觸了關於acm 一點知識,當時還不知道acm是什麼,上網查了後才知道是acm國際大學生程式設計競賽,而且還是由美國計算機協會主辦的,瞬間便感覺這門課非常的高大上,但也有些懷疑自己能否學習這門高大上的課程,於是便抱著試試的態度來進行了一系列的學習。在寒假的期間僅僅是了解了一些基體的知識,然後學習了stl,stl是乙個標準模板庫,裡面有許多的實用的容器,比如說 vector還有map以及在以後用到的佇列以及核等等,還有就是包含了許多實用的演算法,比如常用的sort包含在標頭檔案< algorithm>。

stl內容:

vectors: 

將元素置於乙個動態陣列中加以管理,可以隨機訪問元素(用索引直接訪問),陣列尾部新增或移除元素非常快速。但是在中部或頭部安插元素比較費時;

deques: 

是「double-ended queue」的縮寫,可以隨機訪問元素(用索引直接訪問),陣列頭部和尾部新增或移除元素都非常快速。但是在中部或頭部安插元素比較費時;

lists:雙向鍊錶,不提供隨機訪問(按順序走到需訪問的元素,o(n)),在任何位置上執行插入或刪除動作都非常迅速,內部只需調整一下指標;

2)關聯式容器(associated containers),元素位置取決於特定的排序準則,和插入順序無關, 

set、multiset、map、multimap;

sets/multisets:內部的元素依據其值自動排序,set內的相同數值的元素只能出現一次,multisets內可包含多個數值相同的元素,內部由二叉樹實現(實際上基於紅黑樹(rb-tree)實現),便於查詢;

maps/multimaps:map的元素是成對的鍵值/實值,內部的元素依據其值自動排序,map內的相同數值的元素只能出現一次,multimaps內可包含多個數值相同的元素,內部由二叉樹實現(實際上基於紅黑樹(rb-tree)實現),便於查詢;

而後是學習了遞迴與遞推,遞迴與遞推演算法就是在知道幾個結果的時候,能夠通過一種關係來推出其他的結果,然後通過迴圈來解決問題。遞迴演算法的基本思想是:把規模大的、較難解決的問題變成規模較小的、易解決的同一問題。規模較小的問題又變成規模更小的問題,並且小到一定程度可以直接得出它的解,從而得到原來問題的解。我們利用遞迴演算法解題,首先要對問題的以下三個方面進行分析: 

1.決定問題規模的引數。需要用遞迴演算法解決的問題,其規模通常都是比較大的,在問題中決定規模大小(或問題複雜程度)的量有哪些?把它們找出來。 

2.問題的邊界條件及邊界值(又叫結束條件或出口)。在什麼情況下可以直接得出問題的解?這就是問題的邊界條件及邊界值。 

3.解決問題的通式(又叫遞迴體)。把規模大的、較難解決的問題變成規模較小、易解決的同一問題,需要通過哪些步驟或等式來實現?這是解決遞迴問題的難點。

而後是動態規劃問題,在剛開始學習動態規劃的問題的時候感覺是學的一臉懵逼,感覺什麼都不懂,上課的時候聽得懵懵懂懂,然後回去的時候看了好長時間的解析才弄懂一些最簡單的問題,好在在費了好多時間後終於弄懂了技巧。動態規劃是解決多階段決策問題的一種方法。多階段決策問題是說如果一類問題的求解過程可以分為若干個互相聯絡的階段,在每乙個階段都需作出決策,並影響到下乙個階段的決策。多階段決策問題,就是要在可以選擇的那些策略中間,選取乙個最優策略,使在預定的標準下達到最好的效果。 

動態規劃的指導思想就是在做每一步決策時,列出各種可能的區域性解;依據某種判定條件,捨棄那些肯定不能得到最優解的區域性解;以每一步都是最優的來保證全域性是最優的。 

動態規劃問題具有以下基本特徵: 

問題具有多階段決策的特徵; 

每一階段都有相應的「狀態」與之對應,描述狀態的量稱為「狀態變數」; 

每一階段都面臨乙個決策,選擇不同的決策將會導致下一階段不同的狀態; 

每一階段的最優解問題可以遞迴地歸結為下一階段各個可能狀態的最優解問題,各子問題與原問題具有完全相同的結構。在我看來,動態規劃最重要的是寫出狀態轉移方程,只要寫出狀態轉移方程,一切便迎刃而解,順著思路走,把每乙個細緻的地方弄懂,就能解決問題。

動態規劃例子:0-1揹包問題

問題描述:一共n中物品,每樣物品只有一件,物品i的重量為wi>0,價值為vi,揹包的最終容量為weight,求如何新增物品,在不超過揹包容量的情況下,揹包中物品的價值最大?

狀態轉移方程:dp[j] = max, 其中1=**:

int main()

貪心演算法:(又稱貪婪演算法)

是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的是在某種意義上的區域性最優解。

貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。貪心演算法就是在解決一些選擇當前狀態下的最優解就能夠導致最終的最優的問題的方法。

貪心演算法的基本思路:

1.建立數學模型來描述問題。

2.把求解的問題分成若干個子問題。

3.對每一子問題求解,得到子問題的區域性最優解。

4.把子問題的解區域性最優解合成原來解問題的乙個解。

貪心演算法的最常見的乙個例題就是可以用貪心演算法解決01揹包問題,雖然侷限非常大,但是也是可以解決的。

而後是二分查詢法,二分查詢又稱折半查詢,優點是比較次數少,查詢速度快,平均效能好;其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序列表。首先,假設表中元素是按公升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。

二分查詢可以十分快速的尋找到答案,因為時間複雜度為log2(n),有許多問題都可以用二分查詢來優化,從而避免tle的出現。

二分查詢的乙個簡單例題:輸入n個數,然後輸入乙個數,輸出該數在n個數中的位置。

這個題我們可以用結構體或者map來分別儲存位置與大小,然後按大小排序,然後二分查詢。

二分查詢部分**:

while(1)

cout《在往後則是搜尋,搜尋這一章我感覺十分有趣,搜尋包括三大類,其中有二分搜尋,也就是前面寫的二分查詢,還有就是廣度優先搜尋以及深度優先搜尋,也就是bfs與dfs。

廣度優先搜尋(bfs):

圖的廣度優先遍歷bfs演算法是乙個分層搜尋的過程,和樹的層序遍歷演算法類同,它也需要乙個佇列以保持遍歷過的頂點順序,以便按出隊的順序再去訪問這些頂點的鄰接頂點。

2.基本實現思想

(1)頂點v入佇列。

(2)當佇列非空時則繼續執行,否則演算法結束。

(3)出佇列取得隊頭頂點v;訪問頂點v並標記頂點v已被訪問。

(4)查詢頂點v的第乙個鄰接頂點col。

(5)若v的鄰接頂點col未被訪問過的,則col入佇列。

(6)繼續查詢頂點v的另乙個新的鄰接頂點col,轉到步驟(5)。

直到頂點v的所有未被訪問過的鄰接點處理完。轉到步驟(2)。

廣度優先遍歷圖是以頂點v為起始點,由近至遠,依次訪問和v有路徑相通而且路徑長度為1,2,……的頂點。為了使「先被訪問頂點的鄰接點」先於「後被訪問頂點的鄰接點」被訪問,需設定佇列儲存訪問的頂點。

深度優先搜尋(dfs):

圖的深度優先遍歷類似於樹的前序遍歷。採用的搜尋方法的特點是盡可能先對縱深方向進行搜尋。這種搜尋方法稱為深度優先搜尋(depth-first search)。相應地,用此方法遍歷圖就很自然地稱之為圖的深度優先遍歷

2.基本實現思想:

(1)訪問頂點v;

(2)從v的未被訪問的鄰接點中選取乙個頂點w,從w出發進行深度優先遍歷;

(3)重複上述兩步,直至圖中所有和v有路徑相通的頂點都被訪問到。

二叉樹:

二叉樹是每個節點最多有兩個子樹的樹結構。通常子樹被稱作「左子樹」(left subtree)和「右子樹」(right subtree)。二叉樹常被用於實現二叉查詢樹和二叉堆。

二叉樹的每個結點至多只有二棵子樹(不存在度大於2的結點),二叉樹的子樹有左右之分,次序不能顛倒。二叉樹的第i層至多有2^個結點;深度為k的二叉樹至多有2^k-1個結點;對任何一棵二叉樹t,如果其終端結點數為n_0,度為2的結點數為n_2,則n_0=n_2+1。

一棵深度為k,且有2^k-1個節點稱之為滿二叉樹;深度為k,有n個節點的二叉樹,當且僅當其每乙個節點都與深度為k的滿二叉樹中,序號為1至n的節點對應時,稱之為完全二叉樹。

圖論:圖論〔graph theory〕是數學的乙個分支。它以圖為研究物件。圖論中的圖是由若干給定的點及連線兩點的線所構成的圖形,這種圖形通常用來描述某些事物之間的某種特定關係,用點代表事物,用連線兩點的線表示相應兩個事物間具有這種關係。

學習的圖論的重要問題也就是最小生成樹問題了,最小生成樹性質:設g=(v,e)是乙個連通網路,u是頂點集v的乙個非空真子集。若(u,v)是g中一條「乙個端點在u中(例如:u∈u),另乙個端點不在u中的邊(例如:v∈v-u),且(u,v)具有最小權值,則一定存在g的一棵最小生成樹包括此邊(u,v)。

解決最小生成樹有兩個演算法,分別是kruskal演算法與prim演算法。

圖論這一章感覺自己還沒有學好,許多的知識點還沒有掌握,因此還是需要學習啊。

經過了本學期的學習,也參加了比賽,雖然自己並沒有做出什麼成績,但是卻感覺這一學期十分充實,做了自己想做的事情,感受到了程式的奇妙,雖然偶爾也會感到有些枯燥,但總的來說是值得的,最後也感謝老師一學期詳細而耐心的教導。

ACM 學習總結

優先佇列 乙個擁有權值觀念的queue,自動依照元素的權值排列,權值最高排在前面。預設情況下,priority queue是利用乙個max heap完成的 優先佇列的排序不是線性的排序,而是根據規定的優先順序進行排序。內部排序是二叉樹排序。標頭檔案 include 定義 priority queue...

ACM學習總結

acm是乙個對我們計算機專業是乙個含金量很高的比賽,每乙個對程式設計有一定興趣的人來說一定不會放過這個很好的學習機會,雖然說,我錯過了寒假中的學習機會,但開學後,機會總還是有的。我們第乙個章節主要學習stl,就是標準模板庫,通過合理的運用stl我們一是可以節省大量的步驟,從而節省程式執行的時間,二是...

學習總結 近期acm學習的總結

開學已經乙個月了,對acm的學習也乙個月了,做了一下總結 對自己不好的地方的反省 1.開學一開始學的是stl,不得不說stl是乙個很好的東西,熟練的運用stl大大的減少了 量,也使演算法容易實現。但是我在用stl後使自己產生了一種惰性思維。在兩個星期的stl練習後,我發現自己變得越來越懶,不願意自己...