给定mxn大小的棋盘,使用1x2或2x1大小的骨牌使其完全覆盖且没用重叠,求出所有解,求出共有多少种方法即可。
解;从简单开始研究,以2xn的棋盘为例进行研究
一、2xn骨牌的放置有两种方法
1、横着放加最后一个骨牌竖着放设函数F,此时有F(n-1)种方法
2、竖着放,剩下4个空格横着放两个骨牌,此时有F(n-2)个方法
即2xn的棋盘有F(N)=F(N-1)+F(N-2)个方法,会发现呈斐波那契数列递增。
二、研究3xn棋盘放法
必须是偶数列,n必须是偶数,经递推得到F(N)=4F(N-2)+F(N-4);
因此得到3xn棋盘排序算法
三、mxn棋盘算法
结合2xn和3xn棋盘算法规律总结得到计算mxn棋盘代码
#include <iostream>
using namespace std;
int m,n;
bool **Chess;
int Count=0;
void qi(int i,int j){
if(i==m){Count++;return;} // 完成
if(j==n-1){ // 当前方格位于最后一列
if(Chess[i][j]==0){ // 尚未放置
if(i!=m-1&&Chess[i+1][j]==0){ // 下方可以放置
Chess[i][j]=Chess[i+1][j]=1; // 放置
qi(i+1,0); // 换行
Chess[i][j]=Chess[i+1][j]=0; // 恢复
}
}
else qi(i+1,0); // 换行
}
else{ // 当前方格不在最后一列
if(Chess[i][j]==0){ // 尚未放置
if(i!=m-1&&Chess[i+1][j]==0){ // 下方可以放置
Chess[i][j]=Chess[i+1][j]=1; // 放置
qi(i,j+1); // 右移
Chess[i][j]=Chess[i+1][j]=0; // 恢复
}
if(Chess[i][j+1]==0){ // 右边可以放置
Chess[i][j]=Chess[i][j+1]=1; // 放置
qi(i,j+1); // 右移
Chess[i][j]=Chess[i][j+1]=0; // 恢复
}
}
else qi(i,j+1); /
}
}
int main(){
cin >> m >> n;
bool *p=new bool[m*n];
for(int i=0;i<m*n;i++)p[i]=0;
Chess=new bool*[m];
for(int i=0;i<m;i++)Chess[i]=p+i*n;
qi(0,0);
printf("%d",Count);
delete []Chess;
delete []p;
return 0;
}