又涉及到递归问题,这道题的大致内容是这样的:
(请用递推方式求解)对于一个2行N列的走道。现在用1*2,2*2的砖去铺满。问有多少种不同的方式。下图是一个2行17列的走道的某种铺法。
提示:观察前n个结果,可以得到递推式子;如果N很大,需要高精度计算。
其实这道题,与之前的方格涂色问题很像,说它像不仅因为在思考方式上很像,在最后的代码上也很想像,听我一一道来。
题目提示,先观察前n个结果得到递推式。那我们就把前n个结果列出来。在列的同时,就有一种这样的感觉——就像是在高中化学中写同分异构式,“有序思考”。在这里我就不展示我在草稿纸上列举的了直接说思想。
一、主要思想
和讲解方格涂色问题一样,我先来讲一下我的思路:
每次铺砖时考虑的情况大致类似,所以可以用递归求解。根据最后剩余的列数,我们将本问题分成两种情况:
A:最后剩余一列,那么假设把这列去掉后,其铺砖情况与n-1时的情况一样,而加上后,也只有一种情况所以方法数位pave(n-1)
B:最后剩余两列,那么把这两列先去掉后和n-2的情况一样,加上这两列后一共有三种情况:1*2竖着放2列,1*2横着放,2*2直接填满。因为1*2竖着放和A情况重复,所以方法数为pave(n-2)*2
综上:方法总数=pave(n-1)+2*pave(n-2)
二、具体实现
思路有了,但是其中的pave()函数还没有,这就需要我们动手来操作了。以下是具体实现的代码,如果看过我之前那篇博文的同学可能就会知道,这不是一样的问题嘛!对的,代码几乎一样。
#include<iostream>
using namespace std;
long long pave(int n)
{long long c[3] = { 0 };//保存不使用2*2砖的方法次数c[0] = 1;//由数学逻辑推出c[1] = 3;//同上c[2] = 5;//同上if (n == 1)return 1;else if (n == 2)return 3;else if (n == 3)return 5;elsereturn pave(n - 1) + 2 * pave(n - 2);//用递归求解
}
int main()
{int n;cout << "请输入走道的列数N" << endl;while (cin >> n){if (n == 0){cout << "输入有误,请重新输入!" << endl;continue;}cout << "对应的铺法有:" << endl;cout << pave(n) << endl;cout << "铺砖已完成" << endl;cout << "请输入下一走道的列数:(无其他输入请按EOF结束)" << endl;}return 0;
}