【ybtoj】【递归】【高精度】【例题5】平铺方案

传送门
题目


解题思路

f i f_i fi 2 ∗ i 2*i 2i的方案数

  • i − 1 i-1 i1,放一个竖着的 2 ∗ 1 2*1 21
  • i − 2 i-2 i2
    1.放一个 2 ∗ 2 2*2 22
    2.横着放两个 2 ∗ 1 2*1 21

f i = f i − 2 ∗ 2 + f i − 1 f_i = f_{i - 2} * 2 + f_{i-1} fi=fi22+fi1

样例告诉我们要高精度: )


Code
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int maxn = 300;
int n, a[300], m;
struct DT{
	int aed[310];
}f[300];

DT operator * (DT A, int b){//高精乘
	DT c;
	memset (c.aed, 0, sizeof (c.aed));
	for (int i = maxn; i; i--)
	{
		c.aed[i] += A.aed[i] + A.aed[i];
		c.aed[i - 1] = c.aed[i] / 10;
		c.aed[i] = c.aed[i] % 10;
	}
	return c;
}

DT jia(DT A, DT B){//高精加
	DT c;
	memset (c.aed, 0, sizeof (c.aed));
	for (int i = maxn; i; i--)
	{
		c.aed[i] += A.aed[i] + B.aed[i];
		c.aed[i - 1] = c.aed[i] / 10;
		c.aed[i] = c.aed[i] % 10;
	}
	return c;
}

int main(){
	while ((scanf ("%d", &a[++m])) != (EOF))
		;
	m--;
	sort (a + 1, a + 1 + m);//奇妙输入
	f[0].aed[maxn] = 1, f[1].aed[maxn] = 1, f[2].aed[maxn] = 3;//初始化
	for (int k = 1; k <= m; k++)
	{
		n = a[k];
		for (int i = max(a[k - 1], 3); i <= n; i++)
			f[i] =  jia(f[i - 2] * 2, f[i - 1]);
		int i = 1;
		while (i <= maxn && f[n].aed[i] == 0) i++;
		while (i <= maxn)
		{
			printf ("%d", f[n].aed[i]);
			i++;
		}	
		printf ("\n");
	}  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值