【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");
	}  
}

猜你喜欢

转载自blog.csdn.net/qq_39940018/article/details/111641584