【Leetcode】2320. 统计放置房子的方式数_1608

题目

一条街道上共有 n * 2地块 ,街道的两侧各有 n 个地块。每一边的地块都按从 1n编号。每个地块上都可以放置一所房子。

现要求街道同一侧不能存在两所房子相邻的情况,请你计算并返回放置房屋的方式数目。由于答案可能很大,需要对 \(10^9 + 7\) 取余后再返回。

注意,如果一所房子放置在这条街某一侧上的第 i 个地块,不影响在另一侧的第 i个地块放置房子。

  • \(1\leq n \leq 10^4\)

前言

典型的动态规划,但是依旧存在一些坑。

独立的模块就直接分割为独立的问题求解即可

思路

典型的动态规划,n块地,相邻的不能连接,那么如果当前位置放置,就从上一个位置不放置,当前位置选择不放置,那么上一个位置就随意了。

换句话说,这个不能相邻实际上与Leetcode 那个打家劫舍就是一样的,不能选择连续的两个房子。

本题目是两侧,但是也可以发现的是,题目也是额外说明了两侧直接没有影响,那么实际上一侧的选择与另外一就完全没有关系了。因此我们可以直接对于一侧进行DP,得出的选择方案数为N,那么另一侧也是N,由于没有影响,因此可以自由组合,结果就是N*N

据此进行动态规划的状态转移方程的书写,dp[i][0]表示在i位置选择放置一个房子的方案数,dp[i][1]表示在i位置不选择放置一个房子的方案数。
\(dp[i][0] = dp[i-1][1]\)
\(dp[i][1] = dp[i-1][0] + dp[i-1][1]\)
初始状态\(dp[0][0]=0,dp[0][1]=1\)

根据上述的转移方程,可以看到的是\(dp[i]\)只与\(dp[i-1]\)有关,因此没有必要记录每个位置的dp,缩减空间复杂度为O(C)

class Solution:
    def countHousePlacements(self, n: int) -> int:
        l,r = 0,1
        for i in range(n):
            l,r = r,(l+r)%(10**9+7)
        return pow(l+r,2,10**9+7)

最后的代码使用了pow()函数,其内部算法是快速幂,可以在常数时间内求解任意\(\bold{a^b mod\ c}\)

posted @ 2024-08-31 15:41  TICSMC  阅读(11)  评论(0)    收藏  举报