1. 程式人生 > >HDU2044 一隻小蜜蜂...【遞推】

HDU2044 一隻小蜜蜂...【遞推】

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 81160    Accepted Submission(s): 29106


Problem Description 有一隻經過訓練的蜜蜂只能爬向右側相鄰的蜂房,不能反向爬行。請程式設計計算蜜蜂從蜂房a爬到蜂房b的可能路線數。
其中,蜂房的結構如下所示。


Input 輸入資料的第一行是一個整數N,表示測試例項的個數,然後是N 行資料,每行包含兩個整數a和b(0<a<b<50)。

Output 對於每個測試例項,請輸出蜜蜂從蜂房a爬到蜂房b的可能路線數,每個例項的輸出佔一行。

Sample Input 2 1 2 3 6
Sample Output 1 3
Author lcy
Source

問題簡述

:參見上述連結。

問題分析這個問題非常類似於

站在第n個蜂房想一下,前一步是從哪裡來的,問題就清楚了。

看圖可知,由於蜜蜂每次只能從前1個蜂房前2個蜂房過來,那麼f(n)=f(n-2)+f(n-1)。這部就是一個菲波拉契數列嗎?就是一個遞推問題?

可是,開始時候,蜜蜂是在第1個蜂房,所以數列的開始幾項會有所不同。

f(1)=0,因為蜜蜂開始在第1個蜂房;

f(2)=1,蜜蜂只能從第1個蜂房來到第2個蜂房

f(3)=2,蜜蜂可以從第1個蜂房過來,也可以第2個蜂房過來

f(n)=f(n-2)+f(n-1),n>3。

有了以上的遞推式,一切幾乎就解決了。

還需要考慮的一點是,蜜蜂從a蜂房到b蜂房的各種可能路徑,相當於從第1蜂房到第b-a+1蜂房。

另外一點是,還是先打表吧,以防萬一。

程式說明:(略)。

AC的C語言程式如下:

/* HDU2044 一隻小蜜蜂... */

#include <stdio.h>

#define MAXN 50

typedef unsigned long long ULL;

ULL fn[MAXN+1];

void setfn()
{
    int i;

    fn[0] = 0;
    fn[1] = 0;
    fn[2] = 1;
    fn[3] = 2;
    for(i=4; i<=MAXN; i++)
        fn[i] = fn[i-2] + fn[i-1];
}

int main(void)
{
    int n, a, b;

    // 先打表(以防萬一測試集合大)
    setfn();

    scanf("%d", &n);
    while(n--) {
        // 讀入a和b
        scanf("%d%d", &a, &b);

        // 輸出結果
        printf("%lld\n", fn[b - a + 1]);
    }

    return 0;
}