【Leetcode】2320. 统计放置房子的方式数_1608
题目
一条街道上共有
n * 2个 地块 ,街道的两侧各有n个地块。每一边的地块都按从1到n编号。每个地块上都可以放置一所房子。现要求街道同一侧不能存在两所房子相邻的情况,请你计算并返回放置房屋的方式数目。由于答案可能很大,需要对 \(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}\)。

浙公网安备 33010602011771号