骨牌鋪方格
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 61019 Accepted Submission(s): 29517
Problem Description 在2×n的一個長方形方格中,用一個1× 2的骨牌鋪滿方格,輸入n ,輸出鋪放方案的總數.
例如n=3時,為2× 3方格,骨牌的鋪放方案有三種,如下圖:
Input 輸入資料由多行組成,每行包含一個整數n,表示該測試執行個體的長方形方格的規格是2×n (0<n<=50)。
Output 對于每個測試執行個體,請輸出鋪放方案的總數,每個執行個體的輸出占一行。
Sample Input 1 3 2
Sample Output 1 3 2
【分析】遞推
2*n方格,鋪1*2骨牌。我們可以"自左向右"進行此過程。設f[i]表示用1*2骨牌鋪2*i方格的不同方案總數,由于1*2骨牌既可以橫着放,又可以豎着放,是以:
(1)目前面2*(i-1)方格區域已經鋪滿時:可以豎着放一塊1*2骨牌将整個區域鋪滿,故此時方案總數為f[i-1];
(2)目前面2*(i-2)方格區域已經鋪滿時:可以橫着放兩塊1*2骨牌将整個區域鋪滿,故此時方案總數為f[i-2]。
綜上有遞推式:f[i]=f[i-1]+f[i-2](邊界:f[1]=1【隻能豎着放一塊1*2骨牌】,f[2]=2【豎着或橫着放兩塊1*2骨牌】)。
此遞推式與Fibonacci數列通項公式形式相同,這也說明:Fibonacci數列在遞推中有大用處!
此外,注意精度問題,使用long long int。
#include <stdio.h>
#define maxn 55
typedef long long ll;
ll n;
ll f[maxn];
void getF(ll *a)
{
ll i;
a[1]=1,a[2]=2;
for(i=3;i<maxn;i++)
a[i]=a[i-1]+a[i-2];
}
int main()
{
getF(f);
while(scanf("%lld",&n)!=EOF)
printf("%lld\n",f[n]);
return 0;
}