程序設計與算法(二)算法基礎,講授基本的算法。前置課程爲程序設計入門,後續是C++ OOP,夾在中間的這門課難度不高,使用的工具也比較基礎,這讓PAT甲級滿分的我在聽課時甚至有些尷尬。不過好在課程中使用的都是C++語言,相較於以前學的數據結構課程,這一點讓我無比溫馨。算法
「本課程中一部分的例題,難度與中學信息學奧賽NOIP提升組的較難題至關,也和ACM國際大學生程序設計競賽中的中等題至關。」ACM什麼的我不關心,可是即將參加CCF-S的我懷疑例題是否達到NOIP的難度,由於聽課過程當中幾乎沒有難以理解的地方,甚至不少都是快進跳過的,而練習題也比較輕鬆解決了。然而NOIP題我看一眼就不會作。編程
爲了考試,我得繼續學算法,目前定爲算法設計與分析之入門篇、算法設計與分析之進階篇和《算法導論》。在開始新的課程以前,我先把剛學完的課程總結一下。數組
之前一直以爲枚舉就是把全部可能值窮舉一遍,是很是耗時的。然而不少狀況下只須要對幾個變量進行枚舉,其餘的能夠由此推導出來,這樣枚舉量就能夠指數降低了。事實上不多有題目會容許所有枚舉而不超時。數據結構
遞歸自己沒什麼好講的,從最初學編程就開始接觸了。工具
Boolean Expression這道題爲我未來寫彙編器提供了一點啓發。學習
簡單的整數劃分問題,輸入爲[1,50]的整數,輸出也是一個整數,讓我想到這個問題徹底能夠編譯期完成,而C++模板原本就是擅長遞歸的。有機會專門寫一篇模板元編程,這道題就是一個很好的應用。測試
二分算法已經在搜索等應用中寫了好久了,但它在題目中的用法對我來講是新知識。若是一個輸出量與輸入量是單調的關係,就能夠考慮使用二分算法肯定輸出量受約束時輸入量的極值。優化
徹底不記得分治講了什麼,趕忙回去翻了翻講義。例題和練習都是「輸出前k大的數」和「求排列的逆序數」。我感受這兩個算法都是比較難想的,只有輸入數據規模提示了才能明確優化的目標,即O(n)或O(nlogn)。設計
一個很經常使用的結論是,若是分治後合併的過程的時間複雜度是O(n),那麼整體時間複雜度是O(nlogn)。反過來說,若是能猜出一道題要求寫O(nlogn)的算法,而且能夠用分治解決,合併的過程不能超過O(n)。排序
以前在PAT作題的時候,還沒學DP,就開始作DP的題了。看別人的博文學了01揹包,也利用動規的方法作對過題目。這回是系統的學習了。
課程中講的遞歸化動規的方法我不是很明白,狀態轉移方程比較好理解,只是具體問題中如何肯定變量和轉移方程,須要沉下心來思考。有時候內存會超限,能夠考慮滾動數組。
如今還不怎麼熟練,一小時一題的速度確定是不夠的,還得多作題。以及國慶期間作到這裏的時候POJ崩了,出現了從沒見過的validator error。
學數據結構的時候,DFS好像沒有什麼存在感,拓撲排序、Dijkstra等都是相似BFS的算法,只記得有一些題目DFS和並查集都能解決。
而實際上DFS的能力還挺強的,聽說幾乎全部的圖問題均可以用DFS解決。可是,DFS中須要保存路徑,而且不保證第一個解是最優解。爲了提升效率,能夠加入可行性剪枝與最優性剪枝。
一些問題中變量表明着狀態,狀態之間的轉移與變量之間的關係有關,這樣的問題就能夠等效爲圖,其中狀態爲頂點,關係爲邊,能夠用圖的方法來解決。
第一次見識到算法的證實如此繁瑣。對於一些題目,貪心的取法比較複雜,不容易想到,尤爲是最後一題田忌賽馬,POJ還不給測試數據。後來去查了答案纔會作。
用一句話來總結這門課:原來之前學過的東西還能夠這麼用。