分治---二分搜索,棋盘覆盖
来源:互联网 发布:java输出菱形 编辑:程序博客网 时间:2024/06/16 15:26
参考http://blog.csdn.net/liufeng_king/article/details/8477868
1、分治法
分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。递归的解这些子问题,然后将各子问题的解合并得到原问题的解。
分治法所能解决的问题一般具有以下几个特征:
1) 该问题的规模缩小到一定的程度就可以容易地解决
2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
3) 利用该问题分解出的子问题的解可以合并为该问题的解;
4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
分治法的基本步骤:
分治法在每一层递归上都有三个步骤:
分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题;
合并:将各个子问题的解合并为原问题的解。
它的一般的算法设计模式如下:
Divide-and-Conquer(P) 1. if |P|≤n0 2. then return(ADHOC(P)) 3. 将P分解为较小的子问题 P1 ,P2 ,...,Pk 4. for i←1 to k 5. do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi 6. T ← MERGE(y1,y2,...,yk) △ 合并子问题 7. return(T)
其中|P|表示问题P的规模;n0为一阈值,表示当问题P的规模不超过n0时,问题已容易直接解出,不必再继续分解。ADHOC(P)是该分治法中的基本子算法,用于直接解小规模的问题P。因此,当P的规模不超过n0时直接用算法ADHOC(P)求解。算法MERGE(y1,y2,...,yk)是该分治法中的合并子算法,用于将P的子问题P1 ,P2 ,...,Pk的相应的解y1,y2,...,yk合并为P的解。
2、二分搜索
大部分程序员应该都知道二分搜索的大致原理,这里不再赘述。需要说明的是二分搜索是所有以比较为基础的搜索算法时间复杂度最低的算法。用二叉树描速二分查找算法,最坏情况下与二叉树的最高阶相同。比较二叉树线性查找也可用二叉树表示,最坏情况下比较次数为数组元素数量。
任何一种以比较为基础的搜索算法,其最坏情况所用时间不可能低于O(logn)。
也可见http://blog.csdn.net/qq_22238021/article/details/78225069
#include <iostream>#include <stdio.h>using namespace std;template<class Type>int BinarySearch(Type a[],const Type& x,int n);int main(){ int x = 6; int a[10]; for(int i=0; i<10; i++) a[i] = i + 1; cout<<BinarySearch(a,x,10)<<endl; return 0;}template<class Type>int BinarySearch(Type a[],const Type& x,int n){//a[0...n-1]中搜索x int left = 0; int right = n-1; while(left<=right) { int mid = (left + right)/2; if(x == a[mid]) return mid; if(x>a[mid]) left = mid + 1; else right = mid - 1; } return -1;//未找到x}
3、棋盘覆盖
棋盘覆盖问题。有一个
每次都对分割后的四个小方块进行判断,判断特殊方格是否在里面。这里的判断的方法是每次先记录下整个大方块的左上角(top left coner)方格的行列坐标,然后再与特殊方格坐标进行比较,就可以知道特殊方格是否在该块中。如果特殊方块在里面,这直接递归下去求即可,如果不在,这根据分割的四个方块的不同位置,把右下角、左下角、右上角或者左上角的方格标记为特殊方块,然后继续递归。在递归函数里,还要有一个变量s来记录边的方格数,每次对方块进行划分时,边的方格数都会减半,这个变量是为了方便判断特殊方格的位置。其次还要有一个变tile来记录L型骨牌的数量。
代码:
#include <iostream>#include <stdio.h>using namespace std;int tile = 1;//全局变量 骨牌编号int Board[4][4];//棋盘void ChessBoard(int tr,int tc,int dr,int dc,int size);int main(){ for(int i=0; i<4; i++) for(int j=0; j<4; j++) Board[i][j] = 0; ChessBoard(0,0,2,3,4); for(int i=0; i<4; i++) { for(int j=0; j<4; j++) cout<<Board[i][j]<<" "; cout<<endl; }}/** * tr : 棋盘左上角的行号 tc棋盘左上角的列号 * dr : 特殊方格左上角的行号 dc特殊方格左上角的列号 * size :size = 2^k 棋盘规格为2^k*2^k */void ChessBoard(int tr,int tc,int dr,int dc,int size){ if(size == 1) return; int t = tile++;//L型骨牌编号 int s = size/2;//分割棋盘 //覆盖左上角子棋盘 if(dr<tr+s && dc<tc+s)//特殊方格在此棋盘中 ChessBoard(tr,tc,dr,dc,s); else//特殊方格不在此棋盘中 { //用编号为t的骨牌覆盖右下角 Board[tr+s-1][tc+s-1] = t; //覆盖其余方格 ChessBoard(tr,tc,tr+s-1,tc+s-1,s); } //覆盖右上角子棋盘 if(dr<tr+s && dc>=tc+s)//特殊方格在此棋盘中 ChessBoard(tr,tc+s,dr,dc,s); else//特殊方格不在此棋盘中 { //用编号为t的骨牌覆盖左下角 Board[tr+s-1][tc+s] = t; //覆盖其余方格 ChessBoard(tr,tc+s,tr+s-1,tc+s,s); } //覆盖左下角子棋盘 if(dr>=tr+s && dc<tc+s)//特殊方格在此棋盘中 ChessBoard(tr+s,tc,dr,dc,s); else//特殊方格不在此棋盘中 { //用编号为t的骨牌覆盖右上角 Board[tr+s][tc+s-1] = t; //覆盖其余方格 ChessBoard(tr+s,tc,tr+s,tc+s-1,s); } //覆盖右下角子棋盘 if(dr>=tr+s && dc>=tc+s)//特殊方格在此棋盘中 ChessBoard(tr+s,tc+s,dr,dc,s); else//特殊方格不在此棋盘中 { //用编号为t的骨牌覆盖左上角 Board[tr+s][tc+s] = t; //覆盖其余方格 ChessBoard(tr+s,tc+s,tr+s,tc+s,s); }}
覆盖一个2^k*2^k大小的棋盘需要(4^k-1)/3个L型骨牌
- 分治---二分搜索,棋盘覆盖
- 【分治法】分治法与二分搜索,棋盘覆盖问题
- 0003算法笔记——【分治法】分治法与二分搜索,棋盘覆盖问题
- 0003算法笔记——【分治法】分治法与二分搜索,棋盘覆盖问题
- 03算法笔记——【分治法】分治法与二分搜索,棋盘覆盖问题
- 0003算法笔记——【分治法】分治法与二分搜索,棋盘覆盖问题
- 0003算法笔记——【分治法】分治法与二分搜索,棋盘覆盖问题
- 棋盘覆盖(分治-递归)
- 分治法,棋盘覆盖
- 棋盘覆盖问题【分治】
- 棋盘覆盖-分治
- 分治法:棋盘覆盖
- 分治算法--棋盘覆盖
- 分治-棋盘覆盖问题
- 分治-棋盘覆盖
- 棋盘覆盖(分治、递归)
- 棋盘覆盖问题(分治)
- 分治算法---棋盘覆盖
- Zemax中Binary 2 surface的norm radius
- Video Analysis 相关领域介绍之Video Captioning(视频to文字描述)
- 本地同时安装python2和python3时pip报错
- C++ 国外程序员整理的 C++ 资源大全
- opencl之code builder学习教程3
- 分治---二分搜索,棋盘覆盖
- 一些总结
- 前段,js转义html实体
- JAVA入门(中国大学mook) 第五周 多项式
- 音乐播放器的开发
- JavaScript Array filter() 方法
- GTX TITANX 显卡下显卡驱动和cuda的安装血泪史
- gFTP
- 坐标系及wkid