先看题目:
对于一个2行N列的走道。现在用1*2,2*2的砖去铺满。问有多少种不同的方式。
上图是一个2行17列的走道的某种铺法。
不难看出,本题的核心其实就是用一个1*2或2*2的矩阵去填充一个2*N的矩阵,这跟有一道填色的竞赛题颇为相似,那么本题隶属于OJ的递归I专题,所以自然要用递归前去解答。
思路分析
首先,让我们从特殊推演到一般,假设是一个1*2的矩阵,那么答案很简单,就是用一个1*2去铺他;如果是一个2*2的矩阵,那么可以是1*2两个竖,两个横,一个2*2,一共3种;随后经过严密且复杂的数学推演,可以得到2*3时是5种,2*4时是11种。让我们明显的分析一下吧。
现在得到了一个数列:
1,3,5,11,21,43……————————arrayI
对其进行二级处理,得到:
2,2,6,10,22……——————————arrayII
对其进行三级处理,得到:
0,4,4,12……————————————arrayIII
四级:
4,0,8……——————————————arrayIV
此时规律就有所找寻了
我们设每个array的i项为aI,依次有aII,aIII,aIV……
从arrayI开始:
arrayI-aI=5=1+1+3,arrayI-aII=11=3+3+5……
推广出去,对于其二级,三级,四级都是适用的,所以得到递归式:
f(i)=f(i-1)+f(i-2)*2;
数学表达式:
所以程序也就很清晰了:
程序设计
#include<bits/stdc++.h>
using namespace std;
long long go(int n)//定义递归函数go来表示填色的步骤
{
long long sum[3] = {0};
sum[1] = 1;
sum[2] = 3;
sum[3] = 5;
if(n == 1)
return 1;
if(n == 2)
return 3;
if(n == 3)
return 5;//递归边界
else
return go(n - 2) * 2 + go(n - 1);//递归表达式
}
int main()
{
int step;//宽度
int n;
while(cin >> n)
{
scanf("%d",&step);
go(step);
printf("%d",go(step));//边输入边输出
}
return 0;
}
祝五楼机房同志好运!!
24k24k