
我们用f [ i ] f[i]f[i]表示将面积为2 × i 2 \times i2×i的画布铺满的方案数,首先,当铺满了前2 × ( i − 1 ) 2\times (i-1)2×(i−1)的画布时第i ii块布只能摆放一个I II型积木,故f [ i − 1 ] f[i-1]f[i−1]对f [ i ] f[i]f[i]的贡献为f [ i − 1 ] f[i-1]f[i−1];而当铺满了前2 × ( i − 2 ) 2\times (i-2)2×(i−2)的画布时可以竖放两个I II型积木或横放两个I II型积木,但竖放两个I II型积木就会重复计算一次f [ i − 1 ] f[i-1]f[i−1],故f [ i − 2 ] f[i-2]f[i−2]对f [ i ] f[i]f[i]的贡献为f [ i − 2 ] f[i-2]f[i−2];再来考虑其他情况:显然L LL型积木可以使用的数量只能为偶数,且第i ii(i ii为偶数)个L LL型积木与第i + 1 i+1i+1个之间一定是相匹配的,通过画图可以发现两个相匹配的L型积木之间只能摆放x xx个横向I II型积木(x xx与两个L LL型积木之间的距离有关),而两个相匹配的L LL型积木只有两种摆法,因此可以得出递推式:f [ i ] = f [ i − 1 ] + f [ i − 2 ] + 2 × ∑ j = 0 j − 3 f [ j ] f[i]=f[i-1]+f[i-2]+2\times \sum\limits_{j=0}^{j-3}f[j]f[i]=f[i−1]+f[i−2]+2×j=0∑j−3f[j],用前缀和可以优化到O ( n ) O(n)O(n)
代 码 如 下 : 代码如下:代码如下:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<int, int>;
const int N = 1e7 + 5, mod = 1e9 + 7;
int n;
ll f[N], s[N];
int main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin >> n; f[0] = s[0] = 1;
for(int i = 1; i <= n; i++) {
f[i] = (f[i] + f[i - 1] + f[i - 2]) % mod;
if(i >= 3) f[i] = (f[i] + s[i - 3] * 2) % mod;
s[i] = (s[i - 1] + f[i]) % mod;
}
cout << f[n];
return 0;
}
版权声明:本文为qq_51682942原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。