2022蓝桥杯 G.积木画(优化到一维)

在这里插入图片描述
我们用f [ i ] f[i]f[i]表示将面积为2 × i 2 \times i2×i的画布铺满的方案数,首先,当铺满了前2 × ( i − 1 ) 2\times (i-1)2×(i1)的画布时第i ii块布只能摆放一个I II型积木,故f [ i − 1 ] f[i-1]f[i1]f [ i ] f[i]f[i]的贡献为f [ i − 1 ] f[i-1]f[i1];而当铺满了前2 × ( i − 2 ) 2\times (i-2)2×(i2)的画布时可以竖放两个I II型积木或横放两个I II型积木,但竖放两个I II型积木就会重复计算一次f [ i − 1 ] f[i-1]f[i1],故f [ i − 2 ] f[i-2]f[i2]f [ i ] f[i]f[i]的贡献为f [ i − 2 ] f[i-2]f[i2];再来考虑其他情况:显然L LL型积木可以使用的数量只能为偶数,且第i iii 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[i1]+f[i2]+2×j=0j3f[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版权协议,转载请附上原文出处链接和本声明。