递推--铺砖

有一面积为2xN(1< =N< =10)的地板,给定两种不同瓷砖:一种长度为1x2(可以横竖),另一种长度为2x2,数目不限。要将这个长度为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)

高精度防止超出内存和编译时间。

#include<iostream>
#include<vector>

#include <string>
using namespace std;

int max(int x, int y) {
	if (x > y) {
		return x;
	}
	return y;
}

string myAdd(string a, string b)			//高精度加法 
{
	int n = max(a.size(), b.size()) + 1;
	vector<int>ans(n, 0);//开辟一个足够存储结果的数组,结果的位数最多为 位数最多的那个数的位数加一(考虑进位)
	int i = a.size() - 1, j = b.size() - 1, k = n - 1;//从个位开始通过模拟竖式进行大数加法 
	while (i >= 0 && j >= 0)//当两数均未加完时 
	{
		ans[k--] = (a[i--] - '0') + (b[j--] - '0');//我们让我们的数组存储每一位相加的结果注意将字符串转为整型数字 
	}
	//检测是否有某个数的高位未加完将其直接存入数组中 
	while (j >= 0)
	{
		ans[k--] = (b[j--] - '0');
	}
	while (i >= 0)
	{
		ans[k--] = (a[i--] - '0');
	}
	string c = "";//创建一个字符串去存储答案 
	for (i = n - 1; i>0; i--)//因为之前的竖式加每一位都没考虑进位所以我们从最后开始检查进位 
	{//因为是加法如果有进位最多也就进一 
		if (ans[i] >= 10)//如果大于10说明应该进位那么我们让此位减10它的高一位加1 
		{
			ans[i] -= 10;
			ans[i - 1]++;
		}
		c.insert(0, 1, ans[i] + '0');//处理后的结果转化为字符插入结果字符的首位
	}

	if (ans[0]>0)//检查最最高位是否大于0如果两数相加没有进位那么这一位就是0我们就不必存储它否则则放入字符串 
	{
		c.insert(0, 1, ans[0] + '0');
	}
	return c;//返回答案 
}


string f(int k)
{
	if (k <= 0) return "0";
	if (k == 1) return "1";
	if (k == 2) return "3";
	string sum="0", right="3", left="1";
	int i = 0;
	for (i = 3; i < k + 1; i++) 
	{
		sum = myAdd(right, left);
		sum = myAdd(sum, left);
		left = right;
		right = sum;
	}
	return sum;
}

int main()
{
	int k;
	while (cin >> k)
	{
		cout << f(k)<<endl;
	}

	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌新待开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值