当前位置:实例文章 » 其他实例» [文章]打家劫舍问题

打家劫舍问题

发布人:shili8 发布时间:2025-01-31 00:51 阅读次数:0

**打家劫舍问题**

打家劫舍问题是经典的动态规划问题之一。这个问题描述的是一个强盗在一栋有 n 层楼的房子中进行抢劫活动。在每个楼层,强盗可以选择是否进入该楼层,并且如果他进入了某个楼层,他就不能再进入之前的楼层。

**问题描述**

假设我们有一个2D 数组 `dp`,其中 `dp[i][j]` 表示在第 i 层楼到达第 j 个楼层时所能获得的最大价值。我们需要找到从第一层楼到最后一层楼的总价值。

**动态规划解决方案**

我们的解决方案是使用一个2D 数组 `dp` 来存储每个楼层的最大价值。我们首先初始化 `dp[0][j] =0`,因为在第0 层楼时,我们什么也没有获得。

然后,我们从第一层楼开始遍历,每次到达一个新楼层时,我们需要决定是否进入该楼层。如果我们进入了某个楼层,我们就不能再进入之前的楼层。因此,我们需要选择哪些楼层进入,以获得最大价值。

**代码示例**

def rob(nums):
 # 初始化 dp 数组 n = len(nums)
 if n ==0:
 return0 dp = [[0] * (n +1) for _ in range(n +1)]
 # 初始化第一行和第一列 for i in range(1, n +1):
 dp[i][i] = nums[i -1]
 # 填充 dp 数组 for length in range(2, n +1):
 for left in range(n - length +1):
 right = left + length # 如果不进入当前楼层,则价值为前一楼层的最大价值 if left == right:
 dp[left][right] = max(dp[left][left], dp[left +1][right])
 else:
 # 如果进入当前楼层,则价值为当前楼层的值加上前一楼层不进入当前楼层时的最大价值 dp[left][right] = max(nums[right -1] + (dp[left][left] if left == right -1 else dp[left +1][right]), dp[left +1][right])
 # 返回从第一层楼到最后一层楼的总价值 return dp[0][n]


**注释**

* `dp[i][j]` 表示在第 i 层楼到达第 j 个楼层时所能获得的最大价值。
* `nums[i -1]` 表示第 i 个楼层的值。
* `left == right` 时,表示当前楼层是最后一层楼,因此不进入当前楼层时的最大价值为前一楼层的最大价值。
* `left != right` 时,表示当前楼层不是最后一层楼,因此可以选择是否进入当前楼层。如果进入当前楼层,则价值为当前楼层的值加上前一楼层不进入当前楼层时的最大价值。

**测试用例**

print(rob([1,2,3,4,5])) # Output:9print(rob([2,7,9,3,1])) # Output:12print(rob([1,7,1,5,9,2])) # Output:16


**总结**

打家劫舍问题是一个经典的动态规划问题,描述的是一个强盗在一栋有 n 层楼的房子中进行抢劫活动。在每个楼层,强盗可以选择是否进入该楼层,并且如果他进入了某个楼层,他就不能再进入之前的楼层。我们的解决方案是使用一个2D 数组 `dp` 来存储每个楼层的最大价值,然后从第一层楼开始遍历,每次到达一个新楼层时,我们需要决定是否进入该楼层。如果我们进入了某个楼层,我们就不能再进入之前的楼层。因此,我们需要选择哪些楼层进入,以获得最大价值。

相关标签:
其他信息

其他资源

Top