1:引出
首先用合併排序來引出我們今天的主角,合併排序即使用了分治的策略,它將所要排序的區間劃分為2個子區間,將這兩個子區間分別進行遞迴排好順序,然後合併這兩個子區間(合併過程運用了簡單的雙指標演算法)即獲得原問題的解。其實棋盤覆蓋問題也是這樣的。
2:主角登場
問題:在乙個2k*2k個方格組成的棋盤中,恰有乙個方格與其他方格不同,稱該方格為一特殊方格。在棋盤覆蓋問題中,要用圖示的4種不同形態的l型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個l型骨牌不得重疊覆蓋。
3:解法:左上的子棋盤(若不存在特殊方格)----則將該子棋盤右下角的那個方格假設為特殊方格
右上的子棋盤(若不存在特殊方格)----則將該子棋盤左下角的那個方格假設為特殊方格
左下的子棋盤(若不存在特殊方格)----則將該子棋盤右上角的那個方格假設為特殊方格
右下的子棋盤(若不存在特殊方格)----則將該子棋盤左上角的那個方格假設為特殊方格
當然上面四種,只可能且必定只有三個成立,那三個假設的特殊方格剛好構成乙個l型骨架,我們可以給它們作上相同的標記(標號)。這樣四個子棋盤就分別都和原來的大棋盤類似,我們就可以用遞迴演算法解決。
4:**:
#include
using
namespace std;
//(tr,tc)所要覆蓋棋盤的左上角方格的座標
//(dr,dc)所要覆蓋棋盤的特殊方格的座標
//size是所要覆蓋棋盤的行寬和列寬。
const
int n =10;
int title =1;
//l型骨牌的編號
int board[n]
[n];
//棋盤
void
chessboard
(int tr,
int tc,
int dr,
int dc,
int size)
else
//覆蓋右上角棋盤
if(dr < tr + s && dc >= tc + s)
else
//覆蓋左下角棋盤
if(dr >= tr + s && dc < tc + s )
else
//覆蓋右下角棋盤
if(dr >= tr + s && dc >= tc + s)
else
}void
chessprint
(int size)
cout << endl;}}
intmain()
5:總結:分治策略即將原問題劃分為若干個規模較小而結構與原問題相同或相似的子問題,然後分別解決這些子問題,最後合併子問題,即可得到原問題的解。
一般性的步驟:
1:分解:將原問題劃分為若干個規模較小而結構與原問題相同或相似的子問題
2:解決:遞迴求解所有子問題。
3:合併:將子問題的解合併為原問題的解。
分治 棋盤覆蓋問題
描述 在乙個2 k 2 k個方格組成的棋盤中,任意存在乙個特殊方格,那麼總有 4 k 1 3個l型骨牌可以將剩餘方格完全覆蓋。分析 將棋盤橫豎四等分,則特殊方格必存在於某一區域。存在特殊方格的區域自然可以完全覆蓋,其餘三個無特殊方格的區域必須去掉乙個方格方可用l型骨牌完全覆蓋。故,將三區域相鄰部分用...
分治策略之棋盤覆蓋的C 實現
當k 0時,將 全域性整型變數,用來表示l型骨牌的編號 const int board size 4 int tile 1 int board 4 4 void chessboard int tr,int tc,int dr,int dc,int size if size 1 return 每呼叫一...
遞迴與分治之棋盤覆蓋問題
在乙個2 k 2 k個方格組成的棋盤中,若有乙個方格與其他方格不同,則稱該方格為一特殊方格,且稱該棋盤為乙個特殊棋盤。顯然特殊方格在棋盤上出現的位置有4 k種情形.因而對任何k 0,有4 k種不同的特殊棋盤。下圖所示的特殊棋盤為 k 2 時 16 個特殊棋盤中的乙個。在棋盤覆蓋問題中,要用下圖中 4...