蓝桥杯 2022 省B 积木画

本文介绍了如何使用动态规划方法解决一个关于填满2×2×n画布的不同方式数的问题,通过定义状态转移方程dp[i][j]来计算每一步的方案数,最终输出dp[n][1]作为结果。
摘要由CSDN通过智能技术生成

这是个典型的动态规划问题,重点在于找到他的递推方程。

可简单算出填满第0 1 2 3 4列个数为0 1 2 5 11;
运气好点,找到递推公式dp[i]=2*dp[i-1]+dp[i-3];
直接解决了。

但我们还是按照动态规划一步一步来。

思路分析:

  1. 状态定义

    • dp[i][j] 表示在第 i 步时,处于状态 j 的方案数。其中,状态 j 有三种可能性:
      • j = 0 表示在第 i 步时处于上突状态。
      • j = 1 表示在第 i 步时处于占满状态。
      • j = 2 表示在第 i 步时处于下突状态。
  2. 初始状态

    • 初始时,只有在第 0 步处于占满状态的方案数为 1,其他状态的方案数都为 0,即 dp[0][1] = 1
  3. 状态转移方程

    • 对于每一步 i,可以根据前一步的状态推导出当前步的状态。
    • 上突状态 (j = 0) 可以由下一步的下突状态 (j = 2) 和当前步的占满状态 (j = 1) 推导得到,即 dp[i][0] = (dp[i - 2][1] + dp[i - 1][2]) % mod
    • 占满状态 (j = 1) 可以由前一步的三种状态得到,即 dp[i][1] = ((dp[i - 2][1] + dp[i - 1][1]) % mod + (dp[i - 1][0] + dp[i - 1][2]) % mod) % mod
    • 下突状态 (j = 2) 可以由上一步的下突状态 (j = 0) 和当前步的上突状态 (j = 1) 推导得到,即 dp[i][2] = (dp[i - 2][1] + dp[i - 1][0]) % mod
  4. 边界条件

    • 对于 i = 0i = 1,已知初始状态,无需计算。
    • 对于 i = 2,根据情况可直接给出结果。
  5. 结果输出

    • 输出填满一个大小为 2 × 2 × n 的画布所需的不同方式数,即 dp[n][1]

综上所述,这段代码使用动态规划的思想,通过状态转移方程计算填满画布所需的不同方式数,并输出结果。

#include<iostream>
#include<bits/stdc++.h>
using namespace std;

const int mod = 1e9 + 7; // 定义取模的值

int n, dp[10000005][3]; // n表示输入的整数,dp用于存储状态

int main() {
    cin >> n; // 读取输入的整数

    dp[0][1] = 1; // 初始状态:在第0步处于状态1(即占满状态)的方案数为1

    // 动态规划计算每一步的方案数
    for (int i = 1; i <= n; i++) {
        // 状态转移方程:
        // 0为上突,2为下突,1为占满
        dp[i][0] = (dp[i - 2][1] + dp[i - 1][2]) % mod; // 上突状态的方案数等于在第i-2步处于下突状态的方案数与在第i-1步处于占满状态的方案数之和
        dp[i][1] = ((dp[i - 2][1] + dp[i - 1][1]) % mod + (dp[i - 1][0] + dp[i - 1][2]) % mod) % mod; // 占满状态的方案数等于在第i-2步处于占满状态的方案数与在第i-1步处于占满状态的方案数之和,以及在第i-1步处于上突状态的方案数与下突状态的方案数之和
        dp[i][2] = (dp[i - 2][1] + dp[i - 1][0]) % mod; // 下突状态的方案数等于在第i-2步处于占满状态的方案数与在第i-1步处于上突状态的方案数之和
    }

    cout << dp[n][1]; // 输出填满一个大小为2 × 2 × n的画布所需的不同方式数

    return 0;
}

占满状态有个很不好想到的类型,就是dp[i-2][1],本来我们都是只考虑加一个积木后的情景,因为我们不考虑除了上下突和占满的其他情况,有种情况是0000,这个情况上下两行相差2格,不属
                                                                                          00
于三种情况,而这样的情况,从i-2到i可以有两个横着放的I这种情况,而竖着放的I的情况与i-1加个竖着的I的情况重合了。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值