题目描述
你有一个长为 N 宽为 2 的墙壁,给你两种砖头:一个长 2 宽 1,另一个是 L 型覆盖 3 个单元的砖头。如下图:
0 0
0 00
砖头可以旋转,两种砖头可以无限制提供。你的任务是计算用这两种来覆盖 N\times 2N×2 的墙壁的覆盖方法。例如一个 2\times32×3 的墙可以有 55 种覆盖方法,如下:
012 002 011 001 011
012 112 022 011 001
注意可以使用两种砖头混合起来覆盖,如 2\times42×4 的墙可以这样覆盖:
0112
0012
给定 N,要求计算 2×N 的墙壁的覆盖方法。由于结果很大,所以只要求输出最后 4 位。例 2×13 的覆盖方法为 13465,只需输出 3465 即可。如果答案少于 4 位,就直接输出就可以,不用加前导 0,如 N=3 时输出 5。
输入格式
一个整数 N,表示墙壁的长。
输出格式
输出覆盖方法的最后 4 位,如果不足 4 位就输出整个答案。
输入输出样例
输入 #1复制
13
输出 #1复制
3465
说明/提示
数据保证,1≤N≤1000000。
我们要把前 n 列铺满,有两种,一种占两格,一种占三格,一列接着一列铺,就只有两种结果:一种是前 i 列被铺满了;一种是前 i-1 列铺满了,第 i 列只铺了一个。
建立两个列表 lst1 lst2
lst1 存储前 i 列铺满了的方法数,lst2 存储,第i列只铺了一个的方法数。
初始化
第一列被铺满: lst1[ 0 ] = 1 第二列被铺满: lst1[ 1 ] = 2 (两种情况)
第一列有一个被铺了: lst2[ 0 ] = 0 第二列有一个被铺了: lst2[ 1 ] = 2 (两种情况)
递推
对于第 i 列被填满,有三种情况:
lst1[i] = lst1[i-1] + lst1[i-2] + lst2[i-1]
- 第 i-1 列被填满了 lst1[i-1]
那就只能在第 i 列竖着放一个
- 第 i-2 列被填满了 lst1[i-2]
只能横着放,如果竖着放就会跟上面那个重复
- 第 i-1 列被填了一个 lst2[i-1]
不管 i-1 那一列填的是在上面还是下面,相对应的就只有一种情况
对于第 i 列只填了一个有三种情况:
lst2[i] = lst1[i-2]*2 + lst2[i-1]
- 第 i-2 列被填满了 lst1[i-2]*2
这里面又有两种情况
- 第 i-1 列被填了一个 lst2[i-1]
这就是整个的递推关系,代码其实很简单,就是逻辑问题,蓝桥有一个题就是这个稍微改了下,取四位我就不写了。
n = int(input())
lst1 = [0]*n
lst2 = [0]*n
lst1[0] = 1
lst1[1] = 2
lst2[0] = 0
lst2[1] = 2
for i in range(2,n):
lst1[i] = lst1[i-1] + lst1[i-2] + lst2[i-1]
lst2[i] = lst1[i-2]*2 + lst2[i-1]
print(lst1[n-1])