蓝桥杯 递归练习 覆盖墙壁

题目描述

你有一个长为N宽为2的墙壁,给你两种砖头:一个长2宽1,另一个是L型覆盖3个单元的砖头。如下图:

0  0
0  00

砖头可以旋转,两种砖头可以无限制提供。你的任务是计算用这两种来覆盖N*2的墙壁的覆盖方法。例如一个2*3的墙可以有5种覆盖方法,如下:

012 002 011 001 011  
012 112 022 011 001

注意可以使用两种砖头混合起来覆盖,如2*4的墙可以这样覆盖:

0112
0012

给定N,要求计算2*N的墙壁的覆盖方法。由于结果很大,所以只要求输出最后4位。例如2*13的覆盖方法为13465,只需输出3465即可。如果答案少于4位,就直接输出就可以,不用加0,如N=3,时输出5。

输入格式

一个整数N(1<=N<=1000000),表示墙壁的长。

输出格式

输出覆盖方法的最后4位,如果不足4位就输出整个答案。

输入输出样例

输入 #1

13

输出 #1

3465

 

 

这是一道练习递归/递推思想的一道超好的题目,用到了两个递推公式

 

分析:

- 首先记a[n]为填铺长度为n的墙壁可以采用的方法数,b[n]记为在第n个位置上,只有一半的墙壁已经贴好的方法数

- 首先可得状态转移方程:a[n]=a[n-1]+a[n-2]+2*b[n-1];

- 又可以得到b[n]=a[n-2]+b[n-1];

- 初始条件:a[1]=1,a[2]=2; b[1]=0,b[2]=1;

代码如下:

#include <bits/stdc++.h>
using namespace std;

const int MAX = 1000005;
const int INF = 0x7fffffff;
int N;
int a[MAX],b[MAX];

int main() {
    scanf("%d",&N);
    a[1]=1,a[2]=2;
    b[1]=0,b[2]=1;
    for(int i=3;i<=N;i++) {
        a[i]=(a[i-1]+a[i-2]+2*b[i-1])%10000;
        b[i]=((a[i-2]+b[i-1]))%10000;
    }
    printf("%d\n",a[N]);
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章