1.分治法基本模板
divide-and-comquer(P)
{
if(|P|<=n0)
adhoc(P);
divide P into smaller subinstances P1,P2,...,Pk;
for(i=1;i<=k;i++)
yi=divide-and-comquer(Pi);
return merge(y1,...,yk);
}
a.一般是递归出口
b.将原问题分割成若干子问题,子问题与原问题相同,规模略小
c.合并子问题的解(不是所有分治都有这个)
2.递归与非递归的转换记录
a.尾递归转非递归(一般先写好递归版,再用栈模拟)(本质:还是自顶而下)
尾递归在原问题转换成若干子问题之后,不再合并子问题的解,递归是最后的语句,递归之后不再有操作返回值或局部变量的表达式。
1.循环外压栈初始变量
2.循环以栈空为条件
3.循环内先出栈,恢复局部变量值
4.递归出口处,仍然编写递归出口处代码,由continue代替return来打断余下操作
5.用恢复的局部变量值操作
6.遇到递归处,改成压栈当前局部变量
7.出循环
b.线性(一般)递归转非递归
若用栈模拟递归,保存当前局部变量用以代替递归,但是递归之后,又需要用这些改变后的局部变量(或递归返回值)做子问题的合并,这个对我来说比较难做。所以换个方向,思考记录如下:
1.尾递归转非递归的本质还是自顶而下的处理问题,所以可以用栈轻易模拟
2.非尾递归可以自底而上,来转化递归
尾递归转非递归: 3.棋盘覆盖,4.快速排序
非尾递归转非递归:5.strassen矩阵乘法,6.合并排序
3.棋盘覆盖
a.递归版
#include<iostream>
#include<vector>
using namespace std;
vector< vector<int> > a;
static int tile=1;
void chessBoard(int startx,int starty,int msize,int x,int y)
{
if(msize==1)
{
return;
}
else
{
int g=tile++;//只能用局部变量来赋值,直接用静态变量,递归返回后,余下伪特殊方块的赋值就出问题了。
int tempx=(x-startx)/(msize/2);
int tempy=(y-starty)/(msize/2);
if(tempx==0&&tempy==0)
{
chessBoard(startx,starty,msize/2,x,y);
}
else
{
a[startx+msize/2-1][starty+msize/2-1]=g;
chessBoard(startx,starty,msize/2,startx+msize/2-1,starty+msize/2-1);
}
if(tempx==0&&tempy==1)
{
chessBoard(startx,starty+msize/2,msize/2,x,y);
}
else
{
a[startx+msize/2-1][starty+msize/2]=g;
chessBoard(startx,starty+msize/2,msize/2,startx+msize/2-1,starty+msize/2);
}
if(tempx==1&&tempy==0)
{
chessBoard(startx+msize/2,starty,msize/2,x,y);
}
else
{
a[startx+msize/2][starty+msize/2-1]=g;
chessBoard(startx+msize/2,starty,msize/2,startx+msize/2,starty+msize/2-1);
}
if(tempx==1&&tempy==1)
{
chessBoard(startx+msize/2,starty+msize/2,msize/2,x,y);
}
else
{
a[startx+msize/2][starty+msize/2]=g;
chessBoard(startx+msize/2,starty+msize/2,msize/2,startx+msize/2,starty+msize/2);
}
}
}
int main()
{
//初始化棋盘a,特殊元素赋值0,其余元素赋值-1
int n;
cout<<"please input n!"<<endl;
cin>>n;
vector<int> temp;
for(int j=0;j<n;j++)
{
temp.push_back(-1);
}
for(int i=0;i<n;i++)
{
a.push_back(temp);
}
cout<<"please input the special box coordinates!"<<endl;
int x,y;
cin>>x>>y;
a[x][y]=0;
//特殊元素赋值0,伪特殊元素均大于0,未被标记的均为-1
chessBoard(0,0,n,x,y);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<a[i][j]<<"\t";
}
cout<<endl;
}
}