蓝桥杯2022年第十三届省赛真题-积木画(超详细解析)

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

蓝桥杯2022年第十三届省赛真题-积木画(超详细解析)_第1张图片

同时,小明有一块面积大小为 2 × N 的画布,画布由 2 × N 个 1 × 1 区域构成。小明需要用以上两种积木将画布拼满,他想知道总共有多少种不同的方式? 积木可以任意旋转,且画布的方向固定。

输入格式

输入一个整数 N,表示画布大小。

输出格式

输出一个整数表示答案。由于答案可能很大,所以输出其对 1000000007 取模后的值。

样例输入

3

样例输出

5

提示

五种情况如下图所示,颜色只是为了标识不同的积木:

蓝桥杯2022年第十三届省赛真题-积木画(超详细解析)_第2张图片

对于所有测试用例,1 ≤ N ≤ 10000000.

#include
#include
int dp[10000005];
#define mod 1000000007
//不需要类型

//*分析:一开始想的是二维情况,就很难联想,甚至复杂许多,所以我们可以转化为一维思想,这样思考起来就轻松很多
//我们可以把两个单位面积看成一个,所以三个就是1.5个单位面积,再把画布变为1*N的模式,这样就很好解决了

//还有题设案例可以看出,不同颜色不同位置同形态摆放是不算的,问的是每个方块用不重复的形态摆放才成立
//注意是每个方块不重复的形态,只要有一个方块跟自己之前是不一样的没有出现过的形态都算
//(如横或者竖,不同方块随机的横竖只要不重复,拼好画布,都算成立)

int main()
{
int n;
scanf("%d",&n);
dp[1]=1,dp[2]=2,dp[3]=5;
//先导入2维的正确数据,因为本质上1维和2维的方式是不同的,
//只是我们给了2维的一个1维的环境。
for(int i=4;i<=n;i++)
{
    dp[i]=(dp[i-1]*2%mod+dp[i-3]*1%mod)%mod;//数据大就多取模
    //对于规律题目,就需要用上循环以及递推公式的思想
    //定单个方块情况为A,两个1.5情况为B
    //导入前三个数据后,现在我们一维的角度思考问题
    //分两种情况,单用一个单位面积的方块或者用2个1.5单位面积(因为1.5必须一次用两个才能补满)
    //dp是方法种类,因为A方块中放置同样的位置,在二维矩阵是不同的,有两种摆放方式
     //但是B在矩阵中都是占满高度的,所以只有一种摆放方式。
     //因为是一维,只有一行,根据(*分析)可以判断一维中两种方块交错着摆放还是统一摆放都是一致的
     
     //重点在于只要出现了一个积木它本身从来没有出现过的状态就算一种
     //所以不妨我们直接分为全部为一个方块和2个1.5面积的方块讨论
     //如四个方块的全部种类,A情况(i-1)就是三个方块的总情况*2
     //(因为单个方块有两种摆放方式所以2*2*2*2=dp[i-1]*2;
     //而B(i-3)只有一种摆放方式,故乘*1,类比A情况.
     //就单纯的用一维的角度看这个问题就行了,把dp[i-1]当作前面全是A的方块,把dp[i-3]当作全是B,
     //剩下的带入二维的数据就变成二维了

   //核心就是一维中可以忽视它的形态变换,如条形积木,一个积木没有多种形态可言
   //把它当作一个小的整体,把三个积木也想象成一维下压缩成一个只有一种形态
   //的样子,但是要注意有没有特殊情况.如条形积木本身形态不同摆放
   //会影响结果.
   
}
       printf("%d\n",dp[n]);
        

     
                     
    
    
    return 0;
}
//总结:用一维思想简化对二维的不同形态的讨论
//(仅用讨论I型方块的不同高度形态摆放即可,将复杂问题简化实现
蓝桥杯2022年第十三届省赛真题-积木画(超详细解析)_第3张图片

你可能感兴趣的:(c语言)