上海计算机学会2021年3月月赛C++乙组T3再铺地砖

文章讲述了如何计算给定宽度的道路使用1x1和1x2规格地砖的铺设方案数,利用递推和前缀和的方法,结果对1,000,000,007取模。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

再铺地砖

内存限制: 256 Mb时间限制: 1000 ms

题目描述

有一条道路需要铺设地砖,这条道路由 n×2 个方格组成。存在两种规格的地砖,一种是 1×1 规格的,也就是恰好可以覆盖一个方格,另一种是 1×2 规格的。两种规格的砖头的数量没有限制。请计算有多少种方法,将这条道路铺满地砖。

下图是一个例子:

2.png

其中花纹是 1×1 规格的,灰色是 1×2 规格的,可以竖放也可以横放。注意,如果上下两行都放置 1×2 规格的砖,它们可以不对齐,例如以下放置方法是允许的:

2.png

由于方案数可能很大,输出它模 1,000,000,007 的余数即可。

输入格式

单个正整数:表示 n。

输出格式

单个自然数:表示方案数模 1,000,000,007 的余数。

数据范围
  • 对于 30% 的数据,1≤n≤15;
  • 对于 70% 的数据,1≤n≤50000;
  • 对于 100% 的数据,1≤n≤100000。
样例数据

 输入:
3
输出:
22
输入:
4
输出:
71

解析:对于第a[i]的方案数,个以左边对齐的分割点为递推边界,从边界开始向右不能再划分,以此为原则进行递推,有三种情况:

1.边界为i-1:有两种方案,一是单块1x2,二是两块1x1.即a[i-1]*2

2.边界为i-2:有三种情况,一是两块1x2横放,二是一块1x2,两块1x1,1x2放上边,三同二,1x2放下边,即a[i-2]*3;

         

3.边界为i-3,i-4...1:,对于每个边界,以i-6为例,有两种情况,见下图:

 

可以得出2*(1+a[1]+a[2]+a[3]....a[i-3])种方案。

结合以上三种情况,得出结果为

a[i]=2*(a[i-1]+a[i-2]+....a[1]+1)+a[i-2],把前边的2*()变成前缀和,即可

详见代码:

#include <bits/stdc++.h>
using namespace std;
long long a[100005];
int main() {
    int n;
    cin >> n;
    a[1] = 2; //初始化
    a[2] = 7;
    long long sum = 2 * (1 + a[1]); //初始化前缀和
    for (int i = 3; i <= n; i++) {
        sum += 2 * a[i - 1];//计算前缀和
        sum %= 1000000007;
        a[i] = a[i - 2] + sum;//递推a[i]
        a[i] %= 1000000007;

    }
    cout << a[n] << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长春高老师信奥工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值