回溯和貪心
回溯
意義:程式設計解決問題時,常遇到需要例遍所有可能性來求解問題的情況。此時,回溯將是不錯的選擇。
**示例:
#include #include #include /*這個程式用來測試回溯演算法在解決問題中的應用*/
/*八皇后問題:
經典的八皇后問題,即在乙個8*8的棋盤上放8個皇后,
使得這8個皇后無法互相攻擊( 任意2個皇后不能處於同一行,同一列或是對角線上),
輸出所有可能的擺放情況。
*//*
將以上問題引申成在n*n的棋盤上擺放n個皇后的問題。
以下**就使用了回溯法解決n皇后問題。
*/int place(int*,int);//判斷當前位置擺放皇后是否可行
void nqueens(int*,int);//n皇后問題演算法核心
void printsolution(int*,int);//用於輸出已求出的解決方案
int main()
int place(int *x,int k)//形參x為模擬棋盤的陣列,k為當前放置皇后的行數
}else//如果列數超標,說明當前行無法擺放皇后。
k--;//使k減一,下次迴圈時將重新擺放第k行的皇后
}}void printsolution(int *x,int n)//用於輸出結果的函式
printf("\n");
}printf("\n");
}
結果:
解析:
1.對於place函式中兩個判斷條件的解析:
第乙個判斷條件很好理解:兩個皇后不能在同一列上.
第二個判斷條件是通過線的表示式推斷的。將棋盤視為平面直角座標系,每個皇后作為座標系上乙個特殊的點。則能以每個皇后的座標畫出兩條斜率分別為1和-1的直線
。要保證兩個皇后的位置不衝突,只要保證兩個皇后衍生出的所有直線上都不出現另乙個皇后即可
。(例如:x[i]和x[k]兩個皇后的座標分別是:(i,x[i]),(k,x[k])。則如果兩個皇后出現在同一直線上,必有:y=x+(x[i]-i)和y=x+(x[k]-k)是同一條直線。或y=-x+(x[i]+i)和y=-x+(x[k]+k)是同一條直線
。則可得:x[i]-x[k]=i-k或x[i]-x[k]=k-i。即:|x[i]-x[k]|=|i-k|
2.以上**中的x陣列第0個元素不使用,陣列下標n代表棋盤的第n行,其中的陣列值m代表第n行第m列放置乙個皇后。這種設計保證每行有且只有乙個皇后,規避了大量重複判斷的同時也比二維陣列更節省資源。
3.以上**中nqueens函式使用了迴圈加回溯保證例遍每一種皇后擺放情況。如無法直接理解,可使用單步除錯觀察。
貪心演算法
定義:通過區域性最優達到全域性最優
**示例1:
#include #include /*這個程式用來測試貪心演算法*/
/*對於以下問題:
有3種硬幣,面值分別為1元、5角和1角,各自的數量不限。
設計自動售貨機時,需要為顧客找零錢,請設計程式進行計算,
要求給顧客的硬幣枚數最少
*/int main()
;//儲存著以分為單位的各種貨幣
int x;//x用於儲存需要找零的金錢總數
int i=0,n=0,m;//n用於儲存零錢總枚數
scanf("%d",&x);
/*只要需要找零的金錢數還未歸零,並且還存在面值更小的零錢,就繼續迴圈*/
while(x>0&&money[i]!=0)
if(x==0)//最終,如果成功找零
printf("%d\n",n);//輸出零錢枚數
else
printf("fail\n");//否則,輸出失敗
return 0;
}
結果:
解析:
1.以上程式的核心是:首先用面值較大的零錢進行找零。直到無法找零,再用面值較小的找零。
2.貪心思路:不從整體最優考慮,而是保證所做的每一步選擇都是區域性最優的方案,最終將所有的區域性最優糅合為整體最優。
**示例2:
#include #include /*
貨船裝箱問題
已知一批貨櫃的重量,要將它們裝入乙個載重量為c的貨船中,
在貨船裝載體積不限的前提下,怎樣才能將最多的貨櫃裝上船?
*//*使用貪心法能解決此問題*/
/*設貨船重量c為13,共5個貨櫃重量依次為5,7,6,3,2
只要優先將重量輕的裝上船即可。
*/#define n 50
int main()
/*從小到大將貨櫃裝入貨船,直到無法再裝*/
for(i=0;i結果:
解析:
同樣是很容易理解的貪心思路:要裝入的箱子數目最多,只要將重量小的箱子優先裝入即可。
貪心演算法的核心是:
每次抉擇時,都「貪便宜」。無視這個選擇對未來的抉擇的影響,只選擇當前最優的選項。
這種演算法在大多數情況下並不能使最終結果「最優」,但常常能得到「 較優」的結果。在實際應用時,難點不在於貪心的實現,而在於判斷題目是否可以用貪心來解。以及怎樣的選擇才是「當前最優」的。
演算法學習筆記 貪心演算法
貪心也就是貪婪,就好比我們考試期末成績是由平時分和期末成績兩部分組成,我們複習時肯定是想要在考完當前這門之後的最短的時間內得到最多的分數。這就是貪心的思想。所謂貪心演算法 就是指 我們所做出的選擇在當前情況下總是最好的,它考慮的不是全域性最優解,而是 某種意義上的區域性最優解。核心思想 就是以區域性...
演算法學習筆記 貪心演算法
1 建立數學模型來描述問題 2 把求解的問題分成若干個子問題 3 對每一子問題求解,得到子問題的區域性最優解 4 把子問題的區域性最優解合併成原來解問題的乙個解。1 從問題的某一初始解出發 2 while能向給定總目標前進一步 3 求出可行解的乙個解元素 4 由所有解元素組合成問題的乙個可行解。這個...
貪心演算法 筆記
揹包相關問題。1.給出n 個物品,第i 個物體的重量為wi 選擇盡量多的物體,使得總重量不超過 c 按照物品重量從到小排序 2.部分揹包問題。有 n個物體,第 i 個物體的重量為wi 價值為vi 在總重量超過c的情況下讓總價值盡量高。按照 價值除以重量的值 排序 乘船問題。有 n 個人,第 i個人的...