一: 思想
有時候我們處理乙個複雜的問題,可能此問題求解步驟非常雜,也可能是資料非常多,導致我們當時很難求出或者無法求出,古語有云:
步步為營,各個擊破,這個思想在演算法中稱為分治思想,就是我們可以將該問題分解成若干個子問題,然後我們逐一解決子問題,最後將子問題
的答案組合成整個問題的答案。
二: 條件
當然各個思想都有它的使用領域,所以玩這場分治遊戲就要遵守它的遊戲規則。
① 求解問題確實能夠分解成若干個規模較小的子問題,並且這些子問題最後能夠實現接近或者是o(1)時間求解。
② 各個子問題之間不能有依賴關係,並且這些子問題確實能夠通過組合得到整個問題的解。
三:步驟
通過上面對分治的說明,可以看到分治分三步走:
① 分解: 將問題分解成若干了小問題。
② 求解: o(1)的時間解決該子問題。
③ 合併: 子問題逐一合併構成整個問題的解。
四:舉例
有n位選手參加羽毛球賽,比賽要進行n-1天,每位選手都要與其他每乙個選手比賽一場並且每位選手每天都要比賽一場,請根據比賽要求
排出選手的比賽日程表。
思路:首先我們拿到問題要給自己打氣,哈哈,因為日常的基本問題都跑不出我們所知道演算法思想的範疇,此問題也包括在內。
當n是8,16,32時,面對這麼乙個龐大的問題我們可能就崩潰了,因為我們實在無法求出來,此時我們就要想想是否可以分治一下。
① 就拿16個選手的比賽安排來說,需要比賽15天。
② 分成2個8位選手7天的比賽安排。
③ 分為4個4位選手3天的比賽安排。
④ 分為8個2位選手1天的比賽安排。
相信2位選手1天的比賽安排大家都會吧,如圖:
然後退化到第三步即4位選手3天的比賽安排,如圖:
在圖中可以看出:
第一天:將1,2位和3,4位選手的日程合併。
第二天,第三天:這兩天的比賽安排其實可以發現規律的,整個**可以劃分四格,對角賦值。
程式**如下:
1using system;
2using system.collections.generic;
3using system.linq;
4using system.text;56
namespace fenzhi
7 25
26//
因為我定了只能容納8位選手的日程的比賽安排,多的話就會爆掉
27if (person > 8)
28
3233
//呼叫分值計算函式
34 gamecal(1, person);
3536 console.write("
\n編號\t
");37
38//
最後就是將陣列表頭
39for (int i = 1; i < person; i++)
40 天\t
", i);
42 }
4344
//換行
45 console.writeline();
4647
//輸出陣列內容
48for (int i = 0; i < person; i++)
49 \t
", gamelist[i, j]);
53 }
54 console.writeline();
55 }
5657 console.readline();
58 }
5960
///61
///分治計算
62///
63///
起始選手編號
64///
選手的人數(因為是分治,所以每次砍半)
65static
void gamecal(int index, int num)
66
82else
83
102 }
103104
//用於將「左上角」填充到「右下角」
105//
控制橫座標
分治演算法思想
1.分解 對這k個子問題分別求解。如果子問題的規模仍然不夠小,則再劃分為k個子問題,如此遞迴的進行下去,直到問題規模足夠小,很容易求出其解為止。2.合併 將求出的小規模的問題的解合併為乙個更大規模的問題的解,自底向上逐步求出原來問題的解。3.分治演算法的使用條件 分治法所能解決的問題一般具有以下幾個...
演算法思想 分治演算法
分而治之 大問題能夠拆成相似的小問題,記住這些小問題需要具有相似性。而後將小問題的每個解合成為大問題的解。所以說大問題如何拆,小問題如何合併才是這個演算法最主要的乙個思想。實際上很多演算法如貪心演算法,動態規劃等等都是要求把大問題拆成小問題。而分治演算法的重要一點就是要適用於能夠重新把小問題的解合併...
分治演算法思想介紹
一,介紹 分治演算法主要包含兩個步驟 分 治。分,就是遞迴地將原問題分解成小問題 治則是 在解決了各個小問題之後 各個擊破之後 合併小問題的解,從而得到整個問題的解 二,分治遞迴表示式 分治演算法一般都可以寫出乙個遞迴表示式 比如經典的歸併排序的遞迴表示式 t n 2t n 2 o n t n 代表...