三排地砖(iai一月月赛丙组)

三排地砖

题目描述

有一条道路需要铺设地砖,这条道路由 n×3 个方格组成。只有一种规格的地砖,大小是 1×2 规格的,也就是恰好可以覆盖两个方格。请计算有多少种方法,将这条道路铺满地砖。

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

输入格式
  • 单个整数:表示 nn。(保证nn为偶数)
输出格式
  • 单个整数:表示方案数模 1,000,000,007 的余数。
数据范围
  • 对于 30%30% 的数据,1≤n≤15
  • 对于 70%70% 的数据,1≤n≤300
  • 对于 100%100% 的数据,1≤n≤200000
样例数据

输入:

2

输出:

3

输入:

8

输出:

153

解答

1、想象这是一个类似于俄罗斯方块的游戏,他的底部长度是3,高度则是给定的n

2、那么这样我们就会得到一个长方形,那么现在从天上掉下来的只会是2*1的长方形,区别在于是横着的还是竖着的

3、由于题目给定的n必然是偶数,而且我们需要求的是能填满3*n的长方形,所以这个时候我们对于每一个偶数(i)dp[i]就应该是填满高度为i的方案数

4、那么我们可以思考一下,当我们的i为2的时候一共几种状况呢

通过推算,我们可以得出三种状态

1、全是竖着

2、竖着在左边

3、竖着在右边

我们不难得出判断,这仅仅是我们i为2的状态,并不是所有的都是这样的,也就是所有偶数状态都是这样搭建的

 

例如,我们可以在初期搭建的过程中,在横着的板子上继续防止两个竖着的板子,那么这样组件也是可以的,当然,这种操作仅仅存在于i必须是大于2的情况

现在我们倒推一下表达式

首先,我们必须分为奇数于偶数状态,因为偶数必须是要填满的方案,奇数绝对缺少点什么

我们可以用dp的二维数组

dp 【N】【2】

那么dp【i】【1】代表i为奇数时候,缺少一块位置的方案数

dp【i】【0】代表i为偶数的时候,满格方案数

为什么要这样去表达呢,因为我们会发现,只有当这块板子是横着的时候才会给我们造成麻烦,如果没有横着的时候是不会有麻烦的

如何去写dp表达式呢

首先结合一下我们刚刚想到的竖着板子在横着板子上,他的存在范围是 i 大于2,所以在n<=2的时候我们是递推不了的

接下来看一下这个表达式要怎么去写

首先我们知道

奇数时候,我们希望他只缺一个空位

那么此刻我们要由哪几种状态合成他呢

dp【i-2】【1】上一次只缺一个的情况,此刻我们是需要三个竖着的板子

dp【i-1】【0】这个时侯就只需要在已经做好的方案上添加即可,在这个时候,因为横着板子放的位置不同,所以我们得到的方案也是不相同的

偶数的时候,就是满格状态

dp【i-2】【0】我们可以由上一次满状态得到现在,那么由上面可以得到,我们要能安稳得到,只有三个竖着板子放着的情况

dp【i-1】【1】由只有一个的,那么他装满的情况是固定的

code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5+6;
const int mod = 1e9+7;
ll dp[N][4];//缺两个,缺一个,不缺 
int main() {
    int n;
    cin>>n;
    if(n==2)
    {
        cout<<3;
        return 0;
    }
    dp[2][0]=3;
    //一开始,组合成有三种情况
    dp[1][1]=2;
    //放置分左右情况
    for(int i=3;i<=n;i++)
    {
​
        if(i&1)
        {
            dp[i][1]=(dp[i][1]+dp[i-2][1]+dp[i-1][0]*2)%mod;
        }
        else 
        {
            dp[i][0]=(dp[i][0]+dp[i-1][1]+dp[i-2][0])%mod;  
        }
    }
    cout<<dp[n][0];
    return 0;
}

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值