• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

RomanLin

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【线性DP】LeetCode 2320. 统计放置房子的方式数

题目

https://leetcode.cn/problems/count-number-of-ways-to-place-houses/

题解

由于道路两边的房子彼此互不影响,因此满足相互独立的条件,故而两侧的方案的乘积就是最后的答案。

因为两侧空地的数量都是 \(n\),因此只要算出其中一侧的方案即可,另一侧的方案相同。

每块空地上都可以选择建或者不建房子,但建房子后,其左右两侧相邻空地都不能再建房子。基于此,定义一个二维数组 \(dp[N][2]\),其含义为:

  • \(dp[i][0]\):不在第 \(i\) 块空地上建房子的方案数
  • \(dp[i][1]\):在第 \(i\) 块空地上建房子的方案数

对于第 \(0\) 块空地(也就是没有任何空地的情况),明显无法建任何房子,但没建本身也是一种方案。因此:$$dp[0][0] = 1, dp[0][1] = 0$$
对于第 \(1\) 块空地,不建房子的情况,第 \(0\) 块(即紧邻的上一块空地)可以建也可以不建。建房子的情况,第 \(0\) 块则只能不建。因此:$$dp[1][0] = dp[0][0] + dp[0][1] = 1,dp[1][1] = dp[0][0] = 1$$
对于第 \(i\) 块空地,有:$$dp[i][0] = dp[i - 1][0] + dp[i - 1][1],dp[i][1] = dp[i - 1][0]$$
那么,对于每侧有 \(n\) 块空地的建房子总方案数为:$$(dp[n][0] + dp[n][1]) * (dp[n][0] + dp[n][1])$$

对上述过程,我们可以观察到:

  • \(dp[1][0] = dp[0][0] + dp[0][1] = 1,dp[1][1] = dp[0][0] = 1\)
  • \(dp[1][1] = dp[0][0] = 1\)
  • \(dp[2][0] = dp[1][0] + dp[1][1] = 2\)
  • \(dp[2][1] = dp[1][0] = dp[0][0] + dp[0][1] = 1\)
  • ...
  • \(dp[i][0] = dp[i - 1][0] + dp[i - 1][1]\)
  • \(dp[i][1] = dp[i - 1][0] = dp[i - 2][0] + dp[i - 2][1]\)

那么可以优化为滚动数组,将二维数组优化为一维数组:$$dp[i] = dp[i - 1] + dp[i - 2]$$
优化为一维数组后的总方案数为:\(dp[n] * dp[n]\)

参考代码

二维dp数组
constexpr int MOD = 1e9 + 7;
constexpr int N = 1e4 + 1;
int dp[N][2] = {{1, 0}, {1, 1}};
int init = []() {
    for (int i = 2; i < N; ++ i) {
        dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % MOD;
        dp[i][1] = dp[i - 1][0];
    }
    return 0;
}();

class Solution {
public:
    int countHousePlacements(int n) {
        return (1LL * dp[n][0] + dp[n][1]) % MOD * (1LL * dp[n][0] + dp[n][1]) % MOD;
    }
};
一维dp数组
constexpr int N = 1e4 + 1;
constexpr int MOD = 1e9 + 7;
int dp[N] = {1, 2};
int init = []() {
    for (int i = 2; i < N; ++ i) {
        dp[i] = (dp[i - 1] + dp[i - 2]) % MOD;
    }
    return 0;
}();

class Solution {
public:
    int countHousePlacements(int n) {
        return 1LL * dp[n] * dp[n] % MOD;
    }
};

posted on 2024-12-28 15:47  RomanLin  阅读(26)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3