【墨染】找特有姿态!基于【灵茶山艾府】题解的补充图解

脑筋急转弯

补充证明 灵茶山艾府找不到规律?请看图!(Python/Java/C++/Go)
一定要看链接里的图!本题为看图的形象证明!!

定义: d p [ n ] dp[n] dp[n] 2 × n 2\times n 2×n 矩形的 所有姿态 组成的状态。
一般规律:对于 i + j = n i+j=n i+j=n , d p [ n ] dp[n] dp[n] 包含 d p [ j ] dp[j] dp[j] 拼接 d p [ i ] dp[i] dp[i] 后组成的任何姿态。
如: n = 4 n=4 n=4 d p [ 4 ] dp[4] dp[4] 包含 d p [ 1 ] dp[1] dp[1] 拼接在 d p [ 3 ] dp[3] dp[3] 后组成的任何姿态。

在链接中,找到新规律。从 d p [ 3 ] dp[3] dp[3] 开始,每一个新状态都会多出两种 特有姿态
特有姿态 s p [ i ] sp[i] sp[i] 定义:不由之前状态拼接的全新姿态。
特有姿态如下:
特有姿态

观察,记录 d p [ i ] dp[i] dp[i] 对应的特有姿态 s p [ i ] sp[i] sp[i],有
s p [ 1 ] = s p [ 2 ] = 1 sp[1] = sp[2] = 1 sp[1]=sp[2]=1
s p [ 3 ] = s p [ 4 ] = ⋯ = s p [ n ] = 2 sp[3] = sp[4] = \dots =sp[n]=2 sp[3]=sp[4]==sp[n]=2

对于 i + j = n i+j=n i+j=n ,遍历 i = n − 1 , n − 2 , n − 3 , … , 2 , 1 i = n-1,n-2,n-3,\dots ,2,1 i=n1,n2,n3,,2,1 ; j = 1 , 2 , 3 , … , n − 2 , n − 1 j = 1,2,3,\dots ,n-2,n-1 j=1,2,3,,n2,n1 ,将 j j j 的特有姿态 s p [ j ] sp[j] sp[j] ,拼接在 i i i 的所有姿态 d p [ i ] dp[i] dp[i] 后,就可以 不重不漏 的组成 n n n 的所有姿态 d p [ n ] dp[n] dp[n]

数学证明,可以略过,看结论

(可以不看)得到递推式 ③ d p [ n ] = d p [ n − 1 ] × s p [ 1 ] + d p [ n − 2 ] × s p [ 2 ] + d p [ n − 3 ] × s p [ 3 ] + ⋯ + d p [ 1 ] × s p [ n − 1 ] dp[n] = dp[n-1]\times sp[1] + dp[n-2]\times sp[2] +dp[n-3]\times sp[3] +\dots+dp[1]\times sp[n-1] dp[n]=dp[n1]×sp[1]+dp[n2]×sp[2]+dp[n3]×sp[3]++dp[1]×sp[n1]
①②代入③,得 d p [ n ] = d p [ n − 1 ] + d p [ n − 2 ] + 2 × d p [ n − 3 ] + 2 × d p [ n − 4 ] + ⋯ + 2 × d p [ 1 ] dp[n] = dp[n-1] + dp[n-2] + 2\times dp[n-3] + 2\times dp[n-4] +\dots +2\times dp[1] dp[n]=dp[n1]+dp[n2]+2×dp[n3]+2×dp[n4]++2×dp[1]
整理,得 ④ d p [ n ] = d p [ n − 1 ] + d p [ n − 2 ] + 2 × ( d p [ n − 3 ] + d p [ n − 4 ] + ⋯ + d p [ 1 ] ) dp[n] = dp[n-1] + dp[n-2] + 2\times (dp[n-3] + dp[n-4] +\dots + dp[1]) dp[n]=dp[n1]+dp[n2]+2×(dp[n3]+dp[n4]++dp[1])
又⑤ d p [ n − 1 ] = d p [ n − 2 ] + d p [ n − 3 ] + 2 × ( d p [ n − 4 ] + d p [ n − 5 ] + ⋯ + d p [ 1 ] ) dp[n-1] = dp[n-2] + dp[n-3] + 2\times (dp[n-4] + dp[n-5] +\dots + dp[1]) dp[n1]=dp[n2]+dp[n3]+2×(dp[n4]+dp[n5]++dp[1])

结论

④-⑤,得 d p [ n ] − d p [ n − 1 ] = d p [ n − 1 ] + d p [ n − 3 ] dp[n] - dp[n-1] = dp[n-1]+dp[n-3] dp[n]dp[n1]=dp[n1]+dp[n3]
结论: d p [ n ] = 2 × d p [ n − 1 ] + d p [ n − 3 ] dp[n] = 2\times dp[n-1] + dp[n-3] dp[n]=2×dp[n1]+dp[n3]

思考过程,可以不看

(可以不看) 对于 i + j = n i+j=n i+j=n ,遍历 i = n − 1 , n − 2 , n − 3 , … , 2 , 1 i = n-1,n-2,n-3,\dots ,2,1 i=n1,n2,n3,,2,1 一定有 j = 1 , 2 , 3 , … , n − 2 , n − 1 j = 1,2,3,\dots ,n-2,n-1 j=1,2,3,,n2,n1 ,将 d p [ j ] dp[j] dp[j] 拼接在 d p [ i ] dp[i] dp[i] 后,组成 n n n 的所有姿态 d p [ n ] dp[n] dp[n]。差在包含重复姿态,好在包含所有姿态。对这一步优化,发现了特有姿态 s p sp sp

class Solution {
public:
    int numTilings(int n) {
        long long dp[n+10];
        int mod = 1e9+7;
        memset(dp,0,sizeof dp);
        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 2;
        for(int i = 3;i<=n;i++) dp[i] = (2*dp[i-1] + dp[i-3])%mod;
        return dp[n];
    }
};

时间复杂度 : O ( n ) O(n) O(n)
空间复杂度 : O ( n ) O(n) O(n)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

清墨韵染

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

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

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

打赏作者

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

抵扣说明:

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

余额充值