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


    脑筋急转弯

    补充证明 灵茶山艾府找不到规律?请看图!(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];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

  • 相关阅读:
    xindi-2022-08-23数据分析记录
    解决微信小程序滚动条卡顿的问题
    list的简单模拟实现
    《实战》基于情感词典的文本情感分析与LDA主题分析
    Node.js躬行记(20)——KOA源码分析(下)
    2022.9.14 加字段实战
    linux基础
    大数据工程师的日常工作内容是干嘛?
    Eureka Series : USB / UART / TTL / 232 / 485 Debuger
    信息系统项目管理-组织级项目管理-十八
  • 原文地址:https://blog.csdn.net/Innocence02/article/details/127818766