coursera演算法初步 遞迴 棋盤分割問題

2021-08-08 17:15:37 字數 1843 閱讀 4011

將乙個8*8的棋盤進行如下分割:

將原棋盤割下一塊矩形棋盤並使剩下部分也是矩形,

再將剩下的部分繼續如此分割, 這樣割了(n-1)次後,

連同最後剩下的矩形棋盤共有n塊矩形棋盤.

(每次切割都只能沿著棋盤格仔的邊進行)

注意粗體字「再將剩下的部分繼續切割」,也就是說,被割出去的那一塊是不允許再被切割的。

原棋盤上每一格有乙個分值,

一塊矩形棋盤的總分為其所含各格分值之和

現在需要把棋盤按上述規則分割成 n 塊矩形棋盤,

並使各矩形棋盤總分的均方差最小

輸入 第1行為乙個整數n (1 < n < 15)

第2行至第9行每行為8個小於100的非負整數, 表示棋盤上

相應格仔的分值

每行相鄰兩數之間用乙個空格分隔

輸出 僅乙個數, 為σ(均方差) (四捨五入精確到小數點後三位)

公式如下:

為了使優化目標簡化,將公式裡的內容展開,化簡後得到:

xi是每乙個矩形格的總分。

接下來就是切割方法的問題了。我們先把目光集中到一塊矩形,由於需要一刀把乙個矩形切成兩塊,所以切法是很有限的。就像一般計算機的問題那樣,我們把所有情況列舉出來,該問題就會變得十分清晰。

而切法,也就是如圖四種所示。陰影部分表示切掉的一塊,空白部分表示剩下的部分(也就是n-1塊)。

這道題的目標是求方差最小的切法,經過前面的化簡之後,目標變成了就各個矩形總分平方和最小的辦法。因此,最主要的問題就是構造計算平方和的函式。

因此這道題是用遞迴來解決的,把n塊的問題分解為n-1塊與1塊相加,然後一步步遞迴,每一次遞迴只需要從四種切法當中選乙個最大的切法(當然,從哪個座標開始切還是需要遍歷的)

**如下:

#include

using namespace std;

int s[9][9];//每個格仔的分數

int sum[9][9];//從(1,1)到(i,j)的分數之和,目的是方便各個矩形塊總分的計算

int res[15][9][9][9][9];//fun的記錄表

int calsum(int x1,int y1,int x2,int y2)//計算矩形塊總分

int fun(int n,int x1,int y1,int x2,int y2)

//豎著切的情況

for(a=x1;a

//橫著切的情況

for(b=y1;b

res[n][x1][y1][x2][y2]=min;

return min;

}int main()

double result = n*fun(n,1,1,8,8)-sum[8][8]*sum[8][8];

cout<

return0;}

初步遞迴續

我們來分析ff 3 的實現過程 同樣首先執行ff 3 根據判斷條件執行呼叫ff n 1 也就是ff 2 然後ff 2 呼叫ff 1 ff 1 執行 列印1 執行完畢 這個時候問題出現了,接下來會做什麼呢?我們會想到執行ff 2 但是從哪執行呢 是再次重新執行嗎?這樣肯定不會的否則會陷入無限迴圈中 實...

C語言之演算法初步(漢諾塔 遞迴演算法)

個人覺得漢諾塔這個遞迴演算法比電子老鼠的難了一些,不過一旦理解了也還是可以的,其實網上也有很多 可以直接參考。記得大一開始時就做過漢諾塔的習題,但是那時 寫得很長很長,也是不理解遞迴的結果。現在想起來漢諾塔的演算法就3個步驟 第一,把a上的n 1個盤通過c移動到b。第二,把a上的最下面的盤移到c。第...

python演算法 遞迴演算法和初步了解棧的概念

我們上次學到了選擇排序的演算法,通過學習我們對python中的演算法有了乙個初步的了解,我們再來學習一種我們在python中非常常用和重要的演算法 遞迴,之前我們也通過斐波那契數列來簡單的了解過遞迴 回顧遞迴函式之斐波那契數列 但是我們得明白,遞迴只是讓我們解決問題的方法更加的清晰,但是並沒有在效能...