描述
上一周我們研究了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:
這個是網上別人做的,但是他的用時肯定比我們用快速冪大,其思想如下#include其實仔細想想畫一畫也可以得到遞推公式,假設奇數的方案數不為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];
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 ...