分情况:
{
条形(刚好填满)
{
横着
竖着
L
形(凸出一块)
\left\{ \begin{aligned} & 条形(刚好填满) \left\{ \begin{aligned} 横着\\ 竖着\\ \end{aligned}\right. \\ & L形(凸出一块)\\ \end{aligned} \right.
⎩
⎨
⎧条形(刚好填满){横着竖着L形(凸出一块)
条形
设 F ( n ) F(n) F(n) 长度为 n n n 的方法数
横着
F ( n ) + = F ( n − 1 ) F(n)+=F(n-1) F(n)+=F(n−1)
竖着
F ( n ) + = F ( n − 2 ) F(n)+=F(n-2) F(n)+=F(n−2)
L形
设 G ( n ) G(n) G(n) 为第 n n n 处多出来一块的方案数
G ( n ) = G ( n − 1 ) + F ( n − 2 ) G(n)=G(n-1)+F(n-2) G(n)=G(n−1)+F(n−2)
此为 G G G 的递推公式
答案
F ( n ) = F ( n − 1 ) + F ( n − 2 ) + 2 × G ( n − 1 ) F(n)=F(n-1)+F(n-2)+2\times G(n-1) F(n)=F(n−1)+F(n−2)+2×G(n−1)
此为 F F F 的递推公式
初始条件
F ( 0 ) = 1 F ( 1 ) = 1 F ( 2 ) = 2 G ( 1 ) = 0 G ( 2 ) = 1 G ( 3 ) = 1 G ( 4 ) = 3 F(0)=1\\ F(1)=1\\ F(2)=2\\\ \\ G(1)=0\\ G(2)=1\\ G(3)=1\\ G(4)=3\\ F(0)=1F(1)=1F(2)=2 G(1)=0G(2)=1G(3)=1G(4)=3
变式
G ( n ) − G ( n − 1 ) = F ( n − 2 ) G ( n − 1 ) − G ( n − 2 ) = F ( n − 3 ) ⋯ G ( 4 ) − G ( 3 ) = F ( 2 ) G ( 3 ) − G ( 2 ) = F ( 1 ) G ( 2 ) − G ( 1 ) = F ( 0 ) 累加得 G ( n ) = ∑ k = 0 n − 2 F ( k ) + G ( 1 ) G ( 1 ) = 0 G ( n ) = ∑ k = 0 n − 2 F ( k ) \begin{aligned} &G(n)-G(n-1)=F(n-2)\\ &G(n-1)-G(n-2)=F(n-3)\\ &\cdots\\ &G(4)-G(3)=F(2)\\ &G(3)-G(2)=F(1)\\ &G(2)-G(1)=F(0)\\ &累加得\\ &G(n)=\sum_{k=0}^{n-2} F(k)+G(1)\\ &G(1)=0\\ &G(n)=\sum_{k=0}^{n-2} F(k)\\ \end{aligned} G(n)−G(n−1)=F(n−2)G(n−1)−G(n−2)=F(n−3)⋯G(4)−G(3)=F(2)G(3)−G(2)=F(1)G(2)−G(1)=F(0)累加得G(n)=k=0∑n−2F(k)+G(1)G(1)=0G(n)=k=0∑n−2F(k)
所以 F ( n ) F(n) F(n) 得
F ( n ) = F ( n − 1 ) + F ( n − 2 ) + 2 × G ( n − 1 ) 带入 G ( n − 1 ) 得到 F ( n ) = F ( i − 1 ) + F ( i − 2 ) + 2 × ∑ i = 0 n − 3 F ( i ) \begin{aligned} &F(n)=F(n-1)+F(n-2)+2\times G(n-1)\\ &带入G(n-1)\\ &得到F(n)=F(i-1)+F(i-2)+2\times\sum_{i=0}^{n-3} F(i)\\ \end{aligned} F(n)=F(n−1)+F(n−2)+2×G(n−1)带入G(n−1)得到F(n)=F(i−1)+F(i−2)+2×i=0∑n−3F(i)
代码
#include<iostream>
using namespace std;
const int N = 1e7+9;
int F[N];
int main() {
int n; cin >> n;
int ch = 0;
F[0] = 1; F[1] = 1; F[2] = 2;
for (int i = 3; i <= n; i++) {
ch += F[i - 3];
ch %= 10000;
F[i] = F[i - 1] + F[i - 2] + 2 * ch;
F[i] %= 10000;
}
cout << F[n];
return 0;
}
或者改为
#include<iostream>
using namespace std;
const int N = 1e7 + 9;
int F[N];
int main() {
int n; cin >> n;
int ch = 0;
F[3] = 1;\\表示n=0的时候
for (int i = 4; i <= n+3; i++) {
ch += F[i - 3];
ch %= 10000;
F[i] = F[i - 1] + F[i - 2] + 2 * ch;
F[i] %= 10000;
}
cout << F[n+3];
return 0;
}
由于只用到了 F ( i ) F(i) F(i) F ( i − 1 ) F(i-1) F(i−1) F ( i − 2 ) F(i-2) F(i−2) F ( 3 ) F(3) F(3)
简化为
#include<iostream>
using namespace std;
int main() {
int n; cin >> n;
int ch = 0;
int a = 0, b = 0, c = 1,ans=0;
for (int i = 1; i <= n; i++) {
ch += a;
ch %= 10000;
ans = b + c + 2 * ch;
ans %= 10000;
a = b;
b = c;
c = ans;
}
cout << ans;
return 0;
}
a a a 表示 F [ − 2 ] F[-2] F[−2]
b b b 表示 F [ − 1 ] F[-1] F[−1]
c c c 表示 F [ 0 ] F[0] F[0]
a n s ans ans 表示 F [ 1 ] F[1] F[1]