2022蓝桥杯B组—积木画——递推算法

这篇具有很好参考价值的文章主要介绍了2022蓝桥杯B组—积木画——递推算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

积木画

题目描述

小明最近迷上了积木画,有这么两种类型的积木,分别为 I I I 型(大小为 2 2 2 个单位面积)和 L L L 型(大小为 3 3 3 个单位面积):

2022蓝桥杯B组—积木画——递推算法

同时,小明有一块面积大小为 2 × N 2×N 2×N 的画布,画布由 2 × N 2×N 2×N 1 × 1 1×1 1×1 区域构成。

小明需要用以上两种积木将画布拼满,他想知道总共有多少种不同的方式?

积木可以任意旋转,且画布的方向固定。

输入格式

输入一个整数 N ( 1 ≤ N ≤ 1 0 7 ) N(1\le N \le 10^7) N(1N107),表示画布大小。

输出格式

输出一个整数表示答案。

由于答案可能很大,所以输出其对 1000000007 1000000007 1000000007 取模后的值。


算法:递推 O ( n ) O(n) O(n)

思路
  • 假设没有 L L L 型积木,给你 2 × N 2\times N 2×N 的一个画布 和 I I I 型积木,那么这道题就是简单的递推题。

    • 假设 r e s [ i ] res[i] res[i] 表示在 2 × i 2\times i 2×i 的一个画布放 I I I 型积木,恰好填充完整的方案数。
      1. i = 0 i=0 i=0 时,只有一种方案:不放 → r e s [ 0 ] = 1 \rightarrow res[0]=1 res[0]=1

      2. i ≥ 0 i\ge0 i0

        • 因为我们要保证填放的积木时合法的(也就是最后能把画布刚好填充完)

        • → \rightarrow 这就意味着,我们放 I I I 型积木有两种放法: 2 ∗ 1 、 2 ∗ 2 2*1、2*2 2122

        • 2022蓝桥杯B组—积木画——递推算法

        • 于是,对于 2 × 3 2\times 3 2×3 的画布,我们相当于:

          1. 2 × 2 2\times2 2×2 的画布基础上放置一个 2 × 1 2\times 1 2×1 的积木
          2. 2 × 1 2\times 1 2×1 的画布基础上放置一个 2 × 2 2\times 2 2×2 的积木
        • 图例:2022蓝桥杯B组—积木画——递推算法

        • ⟶ \longrightarrow 于是我们得到了递推公式: r e s [ i ] = r e s [ i − 1 ] + r e s [ i − 2 ] res[i]=res[i-1]+res[i-2] res[i]=res[i1]+res[i2]

  • 那么回到题目,在加入 L L L 型积木后,我们怎么找到递推公式呢?

    • 这里的关键点就在于题目给定的画布为 2 × N 2\times N 2×N,并且我们的方案必定是恰好放完画布。

    • 这就意味着, L L L 型积木一定是成对出现的,不然一定无法恰好放完。

    • 图例:2022蓝桥杯B组—积木画——递推算法

    • 于是我们进一步分析, L L L 型积木一定是成对出现的,意味着我们放 L L L 型积木的时候相当于放一个 2 × 3 2\times 3 2×3 的积木

    • 图例:2022蓝桥杯B组—积木画——递推算法

    • 同时,翻转一下这个 2 × 3 2 \times3 2×3 的积木,也是一种方法

    • 图例:2022蓝桥杯B组—积木画——递推算法

  • 但是这就结束了吗?

    • 仔细观测,我们会发现,虽然 L L L 型积木是成对出现的,但是我们可以在里面穿插 I I I 型积木

    • 例如:2022蓝桥杯B组—积木画——递推算法

    • 随着穿插的 I I I 型积木数量增多,就相当于 2 × 3 、 2 × 4 、 2 × 5 ⋯ 2\times 3、2\times 4、2\times 5\cdots 2×32×42×5 的积木

  • 于是,这道题的题意就变成了:

    • 给定一个 2 × N 2\times N 2×N 的画布,以及 2 × 1 、 2 × 2 、 2 × 3 ⋯ 2\times 1、2\times 2、2\times 3\cdots 2×12×22×3 的积木,其中长度大于 3 3 3 的积木,都有两种,求恰好把画布放完的方案数。
    • 那么假设 r e s [ i ] res[i] res[i] 表示在 2 × i 2\times i 2×i 的画布上放置积木,恰好填充完整个方案的方案数。
      1. i = 0 i=0 i=0 时,只有一种方案:不放 → \rightarrow r e s [ 0 ] = 1 res[0]=1 res[0]=1
      2. i ≥ 1 i\ge 1 i1
        • 如果我们最后一步填充的是 2 × 1 、 2 × 2 2\times 1、2\times 2 2×12×2 的积木,那就相当于 r e s [ i − 1 ] 、 r e s [ i − 2 ] res[i-1]、res[i-2] res[i1]res[i2]
        • 如果我们最后一步填充的是 2 × 3 、 2 × 4 ⋯ 2\times 3、2\times 4\cdots 2×32×4 的积木,那就相当于 2 × r e s [ i − 3 ] 、 2 × r e s [ i − 4 ] 2\times res[i-3]、2\times res[i-4] 2×res[i3]2×res[i4]
        • 于是我们就得到了递推公式:
          • ⟶ r e s [ i ] = r e s [ i − 1 ] + r e s [ i − 2 ] + 2 × ( r e s [ i − 3 ] + r e s [ i − 4 ] + ⋯ + r e s [ 0 ] ) \longrightarrow res[i]=res[i-1]+res[i-2]+2\times (res[i-3]+res[i-4]+\cdots+res[0]) res[i]=res[i1]+res[i2]+2×(res[i3]+res[i4]++res[0])

代码

  • 如果直接实现递推公式,核心代码相当于两层循环 O ( n 2 ) O(n^2) O(n2)

    res[0] = 1;	// 初始化
    for(int i = 1 ; i <= n ; ++i){	// 枚举画布大小
        res[i] = res[i-1];
        if(i >= 2)	res[i] += res[i-2];
        for(int j = i-3 ; j >= 0 ; --j)	res[i] += 2*res[j]; // 枚举长度大于 3 的积木
    }
    
    • 但是由于本题的数据范围为 1 0 7 10^7 107 O ( n 2 ) O(n^2) O(n2) 的算法会导致 T L E TLE TLE
    • 于是,我们需要优化代码,我们仔细观察第二层循环,会发现其实这些状态我们在前面已经计算过了,相当于一个前缀和,于是我们能把第二层循环优化掉。
  • 真正的核心代码 O ( n 2 ) O(n^2) O(n2)

    res[0]=1;	// 初始化
    sum=0;		// 存储 0 ~ (i-3) 的前缀和
    for(int i = 1, j = -2; i <= n ; ++i, ++j){
     	res[i] = res[i-1];
        if(i >= 2)	res[i] += res[i-2];
        if(j >= 0)	sum += res[j];
        res[i] += sum << 1;
    }
    
  • 本题完整代码文章来源地址https://www.toymoban.com/news/detail-422938.html

    #include <iostream>
    using namespace std;
    const int N = 1e7+10, mod = 1e9+7;
    typedef long long ll;
    
    ll res[N];
    
    int main()
    {
        int n;
        cin >> n;
        
        res[0] = 1;
        ll sum = 0;
        for(int i = 1, j = -2 ; i <= n ; ++i, ++j){
            res[i] = res[i-1];
            if(i >= 2) res[i] += res[i-2], res[i] %= mod;
            if(j >= 0) sum += res[j], sum %= mod;
            res[i] += sum << 1, res[i] %= mod;
        }
        cout << res[n] << endl;
        return 0;
    }
    

到了这里,关于2022蓝桥杯B组—积木画——递推算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基础算法-递推算法-学习

    现象: 基础算法-递推算法-学习 方法: 这就是一种递推的算法思想。递推思想的核心就是从已知条件出发,逐步推算出问题的解 最常见案例: 一:正向递推案例: 弹力球回弹问题: * 弹力球从100米高度自由落下, * 每次落地后反跳回原高度的一半,并再落下 * 求它在第1

    2024年02月10日
    浏览(23)
  • 算法中的递推算法

    给定一个数的序列H0,H1,…,Hn,…若存在整数n0,使当nn0时,可以用等号(或大于号、小于号)将Hn与其前面的某些项Hi(0in)联系起来,这样的式子就叫做递推关系。 递推算法是一种简单的算法,即通过已知条件,利用特定关系得出中间推论,直至得到结果的算法。 递推算法分为顺推

    2024年02月12日
    浏览(24)
  • go语言计算推算心率算法 http服务

    为了计算心率和并且将心率计算作为http服务来运行 1 基本数据 a) hrv heart rate variability b) 呼吸 2 傅里叶变换 计算频率 高频和低频 3 隐形马尔科夫 模型 hmm 重在于推测概率 根据最近的心率计算 4 神经网络计算 hrv 5 min RR 间期 平均值标准差 sdann 24h 正常的RR间期总体标准差 s

    2024年02月16日
    浏览(27)
  • 由数据范围反推算法复杂度以及算法内容

    一般编程题目的时间限制是1秒或2秒  在这种情况下,C++代码中的操作次数控制在 为最佳。 下面给出在不同数据范围下,代码的时间复杂度和算法该如何选择: 时间复杂度 对应的数据规模上限(1s时限) 算法 - - 高精度加减、FFT/NTT 高精度乘除 最大公约数、快速幂、数位DP 判断

    2024年03月21日
    浏览(31)
  • 常用算法——递推和递归算法

    一、递推算法: 递推算法是一种顺序递推的数学关系模型算法,好比通项公式。在数值计算的过程之中,只需要知道递推的边界值(一般是初值),也就是最开始的原始数值,然后类推,直到求出第n项数值,也就是目标值为终点。 二、递归算法: 递归算法:在计算机科学中是指

    2024年02月04日
    浏览(35)
  • 算法——动态规划(DP)——递推

    动态规划常用于解决优化问题。 动态规划通常以自底向上或自顶向下的方式进行求解。 自底向上的动态规划从最简单的子问题开始,逐步解决更复杂的问题,直到达到原始问题。 自顶向下的动态规划则从原始问题出发,分解成子问题,并逐步求解这些子问题。 动态规划算法

    2024年01月20日
    浏览(46)
  • 【算法】费解的开关(递推)

    你玩过“拉灯”游戏吗? 25 盏灯排成一个 5×5 的方形。 每一个灯都有一个开关,游戏者可以改变它的状态。 每一步,游戏者可以改变某一个灯的状态。 游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。 我们用数字 1 表示一盏

    2024年02月02日
    浏览(64)
  • 一起学算法(递推篇)

    前言:递推最通俗的理解就是数列,递推和数列的关系就好比算法和数据结构的关系,数列有点像数据结构中的顺序表,而递推就是一个循环或者迭代的过程的枚举过程 1.斐波那契数列 斐波那契数形成的序列称为斐波那契数列,该数列由0和1开始,后面的每一项数字都是前面

    2024年02月14日
    浏览(24)
  • C++基础算法⑤——递推算法(昆虫繁殖 过河卒 Pell数列 上台阶 流感传染 移动路线)

    递推掌握核心: 递推公式(规律) 递推边界(初始化条件) 分析题目意思:如下图 递推式:a[n] = a[n-1]+a[n-2]; 递推边界:a[1]=1 a[2]=2 题目意思:卒从A点到B点可以走哪几条路?有前提条件:卒只能往下或往右走! 马的位置和8个控制点不能走! 由于卒一直往右走,我们知道(0,3)这个

    2024年02月15日
    浏览(26)
  • 某软件的一个模块的需求规格说明书中描述【软件测试题目】

    某软件的一个模块的需求规格说明书中描述 (1)年薪制员工:严重过失,扣年终风险金的4%;过失,扣年终风险金的2% (2)非年薪制员工:严重过失,扣除当月薪资的8%;过失,扣除当月薪资的4% (1)分析原因及结果 原因 c1:年薪制员工 c2:非年薪制员工 c3:过失 c4:严重过失

    2024年02月08日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包