算法描述
分治 ( Divide and Conquer ) ,字面上的解释是“分而治之”,就是把一个复杂的问题划分成多个相同或者相似的子问题,直到子问题可以简单的直接求解,然后将子问题的解进行合并从而得出原问题的解。在计算机科学中,分治法就是运用分治思想的一种很重要的算法。分治法是很多高效算法的基础,如排序算法(快速排序,归并排序),傅里叶变换等等。
其大概流程其实就是分为三步:分解 -> 解决 -> 合并。
- 分解原问题
- 分解到可以求解的边界之后,进行递归求解 ( 分治算法很大程度上是基于递归的 )
- 将子问题的解进行合并
分治法能解决的问题特征:
- 原问题在分解到一定程度就可以容易的解决
- 原问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质,利用该问题分解出的子问题的解可以合并为原问题的解
- 子问题相互独立 ( 如果子问题不相互独立,分治法会造成很多重复的计算,这样的情况我们一般会考虑使用动态规划)
经典例题:棋盘覆盖
棋盘覆盖问题要求在2^k * 2^k 个方格组成的棋盘中,给定了一个特殊点,用一种方案用四种 L 型骨牌实现对除该特殊点的棋盘实现全覆盖。
棋盘如图,黑色为特殊方格要求将L型骨牌放进去 ( 当时老师给的是一个 8*8 的棋盘,看着棋盘整个人都呆住了 )
解决方案就是利用分治法,将棋盘分成四个部分,如果该特殊点在其中的一部分我们就递归他,如果不在,那么我们就假设一个点为特殊点,同样递归下去,直到边长为 1 不可再分。
左上角的子棋盘(若不存在特殊方格):则将该子棋盘右下角的那个方格假设为特殊方格;
右上角的子棋盘(若不存在特殊方格):则将该子棋盘左下角的那个方格假设为特殊方格;
左下角的子棋盘(若不存在特殊方格):则将该子棋盘右上角的那个方格假设为特殊方格;
右下角的子棋盘(若不存在特殊方格):则将该子棋盘左上角的那个方格假设为特殊方格;
这个图可能更加明显的观察出来
具体代码如下
#include <iostream>
#include <math.h>
using namespace std;
int board[101][101];
int tile = 0;
void chessBoard(int tr, int tc, int dr, int dc, int siz) {
if (siz == 1) return;
int t = ++tile;
int new_s = siz / 2;
if (dr < tr + new_s && dc < tc + new_s)//左上
chessBoard(tr, tc, dr, dc, new_s);
else {
board[tr + new_s - 1][tc + new_s - 1] = t;
chessBoard(tr, tc, tr + new_s - 1, tc + new_s - 1, new_s);
}
if (dr < tr + new_s && dc >= tc + new_s)//右上
chessBoard(tr, tc + new_s, dr, dc, new_s);
else {
board[tr + new_s - 1][tc + new_s] = t;
chessBoard(tr, tc + new_s, tr + new_s - 1, tc + new_s, new_s);
}
if (dr >= tr + new_s && dc < tc + new_s)//左下
chessBoard(tr + new_s, tc, dr, dc, new_s);
else {
board[tr + new_s][tc + new_s - 1] = t;
chessBoard(tr + new_s, tc, tr + new_s, tc + new_s - 1, new_s);
}
if (dr >= tr + new_s && dc >= tc + new_s)//右下
chessBoard(tr + new_s, tc + new_s, dr, dc, new_s);
else {
board[tr + new_s][tc + new_s] = t;
chessBoard(tr + new_s, tc + new_s, tr + new_s, tc + new_s, new_s);
}
}
int main() {
int k, r, c, l;
cin >> k >> r >> c;
l = pow(2, k);
chessBoard(0, 0, r, c, l);
for (int i = 0; i < l; i++) {
for (int j = 0; j < l; j++) {
printf("%d ", board[i][j]);
}
printf("\n");
}
return 0;
}