演算法競賽入門經典授課教案第7章暴力求解法

2021-03-28 02:01:17 字數 3551 閱讀 2215

第7章暴力求解法

【教學內容相關章節】

7.1簡單列舉7.2列舉排列7.3子集生成

7.4回溯法7.5隱式圖搜尋

【教學目標】

(1)掌握整數、子串等簡單物件的列舉方法;

(2)熟練掌握排列生成的遞迴方法;

(3)熟練掌握用「下乙個排列」列舉全排列的方法;

(4)理解解答樹,並能估算典型解答樹的結點數;

(5)熟練掌握子集生成的增量法、位向量法和二進位制法;

(6)熟練掌握回溯法框架,並能理解為什麼它往往比生成-測試法高效;

(7)熟練掌握解答樹的寬度優先搜尋和迭代加深搜尋;

(8)理解倒水問題的狀態圖與八皇后問題的解答樹的本質區別;

(9)熟練掌握八數碼問題的bfs實現;

(10)熟練掌握集合的兩種典型實現——hash表和stl集合。

【教學要求】

掌握整數、子串等簡單物件的列舉方法;熟練掌握排列生成的遞迴方法;熟練掌握用「下乙個排列」列舉全排列的方法;理解子集樹和排列樹;熟練掌握回溯法框架;熟練掌握解答樹的寬度優先搜尋和迭代搜尋;熟練掌握集合的兩種典型實現——hash表和stl集合。

【教學內容提要】

本章主要討論暴力法(也叫窮舉法、蠻力法),它要求調設計者找出所有可能的方法,然後選擇其中的一種方法,若該方法不可行則試探下一種可能的方法。介紹了排列生成的遞迴方法;在求解的過程中,提出了解答樹的概念(如子集樹和排列樹);介紹了回溯法的基本框架;介紹了集合的兩種典型實現——hash表和stl集合。

【教學重點、難點】

教學重點:

(1)熟練掌握排列生成的遞迴方法;

(2)理解解答樹,並能估算典型解答樹的結點數;

(3)熟練掌握子集生成的增量法、位向量法和二進位制法;

(4)熟練掌握回溯法框架,並能理解為什麼它往往比生成-測試法高效;

(5)熟練掌握解答樹的寬度優先搜尋和迭代搜尋;

(6)熟練掌握集合的兩種典型實現——hash表和stl集合。

教學難點:

(1)熟練掌握子集生成的增量法、位向量法和二進位制法;

(2)熟練掌握回溯法框架,並能理解為什麼它往往比生成-測試法高效;

(3)熟練掌握解答樹的寬度優先搜尋和迭代搜尋;

(4)熟練掌握集合的兩種典型實現——hash表和stl集合。

【課時安排】

7.1簡單列舉7.2列舉排列7.3子集生成

7.4回溯法7.5隱式圖搜尋

引言暴力法也稱為窮舉法、蠻力法,它要求調設計者找出所有可能的方法,然後選擇其中的一種方法,若該方法不可行則試探下一種可能的方法。

暴力法也是一種直接解決問題的方法,常常直接基於問題的描述和所涉及的概念定義。

暴力法不是乙個最好的演算法,但當我們想不出更好的辦法時,它也是一種有效的解決問題的方法。

暴力法的優點是邏輯清晰,編寫程式簡潔。在程式設計競賽時,時間緊張,相對於高效的、巧妙的演算法,暴力法編寫的程式簡單,能更快地解決問題。同時蠻力法也是很多演算法的基礎,可以在蠻力法的基礎上加以優化,得到更高效的演算法。

而且,某些情況下,演算法規模不大,使用優化的演算法沒有必要,而且某些優化演算法本身較複雜,在規模不在時可能因為複雜的演算法浪費時間,反而不如簡單的暴力搜尋。

使用暴力法常用如下幾種情況:

(1)搜尋所有的解空間;

(2)搜尋所有的路徑;

(3)直接計算;

(4)模擬和**。

7.1 簡單列舉

在列舉複雜物件之前,先嘗試著列舉一些相對簡單的東西,如整數、子串等。暴力列舉對問題進行一定的分析往往會讓演算法更加簡潔、高效。

7.1.1 除法

輸入正整數n,按從小到大的順序輸出所有形如abcde/fghij=n的表示式,其中a~j恰好為數字0~9的乙個排列,2≤n≤79。

樣例輸入:

62樣例輸出:

79546/01283=62

94736/01528=62

【分析】

只需要列舉fghij就可以計算出abcde,然後判斷是否所有數字都不相同即可。不僅程式簡單,而列舉量也從10!=3628800降低至不到1萬。

由此可見,即使採用暴力列舉,也是需要認真分析問題。

完整的程式如下:

#include

using namespace std;

bool test(int i,int j); //初始化陣列t,使得各位數字為0,好處是使得fghij<10000時f位置為0

int ia = 0;

while(i)

while(j)

//判斷a~j是否恰好為數字的0~9的乙個排列

for(int m = 0; m < 10; ++m)

for(int n = m+1; n < 10; ++n)

if(t[n] == t[m]) return false;

return true;

}int main()

}++k;

}} return 0;

}7.1.2 最大乘積

輸入n個元素組成的序列s,你需要找出乙個乘積最大的連續子串行。如果這個最大的乘積不是正整,應輸出-1(表示無解)。1≤n≤18,-10≤si≤10。

樣例輸入:

32 4 -3

52 5 -1 2 -1

樣例輸出:820

【分析】

連續子串行有兩個要素:起點和終點,因此只需要列舉起點和終點即可。由於每個元素的絕對值不超過10,一共又不超過18個元素,最大可能的乘積示會超過1018,可以用long long存下。

完整的程式如下:

#include

int main()

if(ans>0)

printf("%i64d\n",ans);

else

printf("%d\n",-1);

}return 0;

}7.1.3 分數拆分

輸入正整數k,找到所有的正整數x≥y,使得。

樣例輸入:212

樣例輸出:

21/2=1/6+1/3

1/2=1/4+1/4

81/12=1/156+1/13

1/12=1/84+1/14

1/12=1/60+1/15

1/12=1/48+1/16

1/12=1/36+1/18

1/12=1/30+1/20

1/12=1/28+1/21

1/12=1/24+1/24

【分析】

找出所有有x,y,列舉完成了就行了。但是從1/12=1/156+1/13可以看出,x可以比y大很多。由於x≥y,有,因此,即y≤2k。

這樣,只需要在2k範圍內列舉y,然後根據y嘗試計算出x即可。

完整的程式如下:

#include

int main()

printf("%d\n",count); //輸出滿足條件的等式的個數

for(y = k+1; y <= 2 * k; y++)

} return 0;

}7.1.4 雙基回文數

如果乙個正整數n至少有兩個不同的進製b1和b2下都是回文數(2≤b1,b2≤10),則稱n是雙基回文數(注意,回文數不以包含前導零)。輸入正整數s<106,輸出比s大的最小雙基回文數。

第7章能量的釋放與呼吸教案

泰州市九龍實驗學校一年級生物上冊教案2013 2014學年度第一學期課題教學時間 第周星期第節 總課時主備人 執教者唐久義二次備課 唐久義教學內容 第7章能量的釋放與呼吸教學目標 1 知識目標 1 從生物體進行生命活動需要能量這個角度了解能量的釋放與呼吸的關係 2 描述什麼叫呼吸作用。和呼吸有什麼區...

第7章演算法程式與計算系統之靈魂練習題答案解析

1 演算法就是乙個有窮規則的集合,其中之規則規定了解決某一特定型別問題的乙個運算序列。回答下列問題。1 關於演算法的特性,下列說法不正確的是 a 演算法必須有明確的結束條件,即演算法應該能夠結束,此即演算法的有窮性 b 演算法的步驟必須要確切地定義,不能有歧義性,此即演算法的確定性 c 演算法可以有...

2019高考物理教案全集 經典實用 第13章《電磁感應》

第十三章電磁感應 第一單元電磁感應現象法拉第電磁感應定律 基礎知識 一 電磁感應 1 電磁感應現象 只要穿過閉合迴路的磁通量發生變化,閉合迴路中就有電流產生,這種利用磁場產生電流的現象叫做電磁感應,產生的電流叫做感應電流 2 產生感應電流的條件 閉合迴路中磁通量發生變化 3.引起磁通量變化的常見情況...