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

在这里插入图片描述
我们用 f [ i ] f[i] f[i]表示将面积为 2 × i 2 \times i 2×i的画布铺满的方案数,首先,当铺满了前 2 × ( i − 1 ) 2\times (i-1) 2×(i1)的画布时第 i i i块布只能摆放一个 I I I型积木,故 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 I I型积木或横放两个 I I I型积木,但竖放两个 I I I型积木就会重复计算一次 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 L L型积木可以使用的数量只能为偶数,且第 i i i i i i为偶数)个 L L L型积木与第 i + 1 i+1 i+1个之间一定是相匹配的,通过画图可以发现两个相匹配的L型积木之间只能摆放 x x x个横向 I I I型积木( x x x与两个 L L L型积木之间的距离有关),而两个相匹配的 L L L型积木只有两种摆法,因此可以得出递推式: 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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值