HDU 2046 骨牌鋪方格(斐波那契遞推 或者 狀壓DP)

原題地址

骨牌鋪方格

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


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

鋪地板問題,第一時間想到了狀壓DP。於是敲了一發狀壓DP,AC了。

但是測試數據的時候,驚奇地發現這是一個斐波那契數列!

於是試着用遞推去做。


我發現,2*n的地板,可以看做是2*(n-1)的地板加上一個豎放的一個2*1骨牌。也可以看成是一個2*(n-2)的地板加上兩個橫放的2*1骨牌。

所以,f(n)=f(n-1)+ f(n-2)

所以他是個斐波那契數列。




兩個代碼都AC了,要注意的是,斐波那契數列增長速度很快,要用long long。


狀壓DP  AC代碼:
#include<stdio.h>
#include<cstring>
typedef long long ll;
const ll H=1<<2;
const int m=2;
ll dp[55][H];

bool check(int k,int m);

void searchs(int n,int m);

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        searchs(n,m);
        printf("%lld\n",dp[n+1][0]);
    }
    return 0;
}

void searchs(int n,int m)
{
    int W=(1<<m)-1;
    memset(dp,0,sizeof(dp));
    dp[1][0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=W;j++)
        {
            for(int k=0;k<=W;k++)
            {
                if(((j&k)==0)&&check(j|k,m))
                {
                    dp[i+1][j]+=dp[i][k];
                }
            }
        }
    }
    return;
}

bool check(int k,int m)
{
    for(int i=0;i<m;)
    {
        if((k&(1<<i))==0)
        {
            if(i==m-1)
            {
                return 0;
            }
            if((k&(1<<(i+1)))!=0)
            {
                return 0;
            }
            i+=2;
        }
        else
        {
            i++;
        }
    }
    return 1;
}


斐波那契數列AC代碼:
#include<stdio.h>
#include<cstring>
using namespace std;
long long fei[66];
int main()
{
    fei[0]=1;
    fei[1]=1;
    for(int i=2;i<55;i++)
    {
        fei[i]=fei[i-1]+fei[i-2];
    }
    int n;
    while(~scanf("%d",&n))
    {
        printf("%lld\n",fei[n]);
    }
    return 0;
}



發佈了51 篇原創文章 · 獲贊 8 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章