五大算法來自於這裏
分治算法
分而治之:將一個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。
分治法在每一層遞歸上都有三個步驟:
step1 分解:將原問題分解爲若干個規模較小,相互獨立,與原問題形式相同的子問題;
step2 解決:若子問題規模較小而容易被解決則直接解,否則遞歸地解各個子問題
step3 合併:將各個子問題的解合併爲原問題的解。
其中最後一步,合併,是分治算法的特點。一般的用動態規劃就好。
動態規劃
特點:子問題的解有重疊部分,中間結果可以cache。逆推。
keys: 狀態變量,中間結果,轉移方程
動態規劃在每一層遞歸上都有兩個步驟:
step1 判斷是否到邊界
step2 狀態轉移方程
模板:
ArrayList<ArrayList<T>> totalResult \\全局變量
void DP(map, intermediateResult, currentState){
if(currentState==邊界){
新變量 = new(intermediateResult) \\for safety
totalResult.add( 新變量)
}
else{
//自定義操作.....
intermediateResult.add()
DP(map, intermediateResult, NextState)
intermediateResult.remove() //如果求全集,就不remove
//自定義操作....
}
}
貪心算法
特點: 貪心法一般是來求解最優問題的,而且他們其實都是在對問題的狀態空間樹進行搜索,在這個狀態空間樹中搜索最佳的路徑以便求出最優策略。而貪心法是從上到下只進行深度搜索的,它的代價取決於子問題的數目,也就是樹的高度,每次在當前問題的狀態上作出的選擇都是1,也就是說,它其實是不進行廣度搜索的,這也造成了它的一個缺點:它得出的解不一定是最優解,很有可能是近似最優解。
回溯
https://segmentfault.com/a/1190000006121957
特點:在狀態空間樹進行先深度搜索,再廣度搜索。
key: 決策函數
模板:
全局變量 finalResult;
void backTracking(intermediateResult, state){
if(葉子節點)
return ;
if(intermediateResult滿足決策函數){
finalResult.add(intermediateResult)
return finalResult;
}
for(所有路徑){//廣度搜索
backTracking(intermediateResult,nextState);//深度搜索
}
return ;
}