解题思路
设 f i f_i fi为 2 ∗ i 2*i 2∗i的方案数
- i − 1 i-1 i−1,放一个竖着的 2 ∗ 1 2*1 2∗1
- i − 2 i-2 i−2
1.放一个 2 ∗ 2 2*2 2∗2
2.横着放两个 2 ∗ 1 2*1 2∗1
f i = f i − 2 ∗ 2 + f i − 1 f_i = f_{i - 2} * 2 + f_{i-1} fi=fi−2∗2+fi−1
样例告诉我们要高精度: )
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");
}
}