藍橋杯 遞歸練習 覆蓋牆壁

題目描述

你有一個長爲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]);
}

 

 

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