2015程式設計之美 骨牌覆蓋問題 二 快速冪

2021-07-01 22:40:30 字數 1723 閱讀 3891

描述

上一周我們研究了2xn的骨牌問題,這一周我們不妨加大一下難度,研究一下3xn的骨牌問題?

所以我們的題目是:對於3xn的棋盤,使用1x2的骨牌去覆蓋一共有多少種不同的覆蓋方法呢?

首先我們可以肯定,奇數長度一定是沒有辦法覆蓋的;對於偶數長度,比如2,4,我們有下面幾種覆蓋方式:

輸入第1行:1個整數n。表示棋盤長度。1≤n≤100,000,000

輸出第1行:1個整數,表示覆蓋方案數 mod 12357

樣例輸入

62247088
樣例輸出

4037
在2xn的骨牌覆蓋問題中,我們有遞推式子 (0,1)xm^n=(f[n-1],f[n])。

我們考慮能否在3xn的情況下找到同樣的式子。

但在實際的推導過程可以發現,對於3xn的覆蓋,對應的f數值公式比2xn複雜太多。我們需要換個角度來思考推導公式。

在我們放置骨牌的過程中,一定是放好一行之後再放置下一行。根據擺放的方式,可能會產生很多種不同的形狀,而這些形狀之間是否具有某些遞推關係呢?

如果他們存在一定的遞推關係,則我們可以根據第i行的方案數來推導第i+1行的方案數。這樣一行一行推導,直到第n行時不就得到了我們要求的方案數了麼?

那麼來研究一下是否存在這樣的推導公式吧

假設我們已經放好了一些骨牌,對於當前最後一列(第i列)骨牌,可能有8種情況:

對於上面這8種狀態,我們用數字來標記它們。以有放置骨牌的格仔為1,未放置為0,轉化為2進製數

以最下面一行作為1,則有:

接下來考慮如何放置骨牌,我們先將棋盤旋轉一下。假設我們正在放置第i行的骨牌,那麼會有下面3種方式:

灰色表示已經有的骨牌,綠色表示新放置的骨牌。

每一種放置方法解釋如下,假設當第i行的狀態為x,第i-1行的狀態為y:

這個是網上別人做的,但是他的用時肯定比我們用快速冪大,其思想如下

其實仔細想想畫一畫也可以得到遞推公式,假設奇數的方案數不為0,只要有乙個方塊達到奇數長度,就算是其中乙個方案,那麼有:

a[0] = 0; a[1] = 2; a[2] = 3;

對於奇數:a[i] = 2*a[i-1] + a[i-2];  對於偶數:a[i] = 3*a[i-2] + a[i-3];

#include

using namespace std;

const long long mod=12357;

long long n,a[5];

void solve()

cout<>n)

;node mul(node a,node b)

node pow(node m,long long n)

return res;

}int main()

{    long long n;

while(cin>>n)

{if(n&1)

{cout<

2015程式設計之美 骨牌覆蓋問題 一(矩陣快速冪)

描述 骨牌,一種古老的玩具。今天我們要研究的是骨牌的覆蓋問題 我們有乙個2xn的長條形棋盤,然後用1x2的骨牌去覆蓋整個棋盤。對於這個棋盤,一共有多少種不同的覆蓋方法呢?舉個例子,對於長度為1到3的棋盤,我們有下面幾種覆蓋方式 輸入第1行 1個整數n。表示棋盤長度。1 n 100,000,000 輸...

骨牌覆蓋問題二

描述 上一周我們研究了2xn的骨牌問題,這一周我們不妨加大一下難度,研究一下3xn的骨牌問題?所以我們的題目是 對於3xn的棋盤,使用1x2的骨牌去覆蓋一共有多少種不同的覆蓋方法呢?首先我們可以肯定,奇數長度一定是沒有辦法覆蓋的 對於偶數長度,比如2,4,我們有下面幾種覆蓋方式 輸入第1行 1個整數...

程式設計之美2015初賽A

時間限制 2000ms 單點時限 1000ms 記憶體限制 256mb 兩個數a和 b a第一行為乙個數t,為資料組數。之後每組資料報含兩行。第一行為n,為集合s的大小。第二行為n個整數,表示集合內的數。對於每組資料輸出一行,形如 case x y x為資料編號,從1開始,y為最大的子集的大小。1 ...