初学python记录:力扣2312. 卖木头块

文章讲述了如何利用动态规划解决一个关于切割矩形木块以获取最大收益的问题,通过定义状态(木块尺寸和收益)和状态转移方程(考虑切割方式),确定切割策略以得到最大价值。
摘要由CSDN通过智能技术生成

题目:

给你两个整数 m 和 n ,分别表示一块矩形木块的高和宽。同时给你一个二维整数数组 prices ,其中 prices[i] = [hi, wi, pricei] 表示你可以以 pricei 元的价格卖一块高为 hi 宽为 wi 的矩形木块。

每一次操作中,你必须按下述方式之一执行切割操作,以得到两块更小的矩形木块:

  • 沿垂直方向按高度 完全 切割木块,或
  • 沿水平方向按宽度 完全 切割木块

在将一块木块切成若干小木块后,你可以根据 prices 卖木块。你可以卖多块同样尺寸的木块。你不需要将所有小木块都卖出去。你 不能 旋转切好后木块的高和宽。

请你返回切割一块大小为 m x n 的木块后,能得到的 最多 钱数。

注意你可以切割木块任意次。

思考:

1. 可能会用不同切割方式得到相同尺寸的木块 ----> 可能要多次计算同一个尺寸的木块的最大收益 ---->  重叠子问题(将已经计算过的尺寸的木块的收益记录下来避免重复计算)

2. 求得到的最多钱 ----> 求能得到最多钱的切割方法 ----> 计算每一种尺寸(不超过m*n大小)的木块的最优切割方法

因此,动态规划适用于这个问题:动态规划(Dynamic Programming,简称DP)通常用于优化问题的求解。它通常用于解决具有重叠子问题和最优子结构性质的问题。使用动态规划解决问题需要考虑两个关键步骤:确定状态和状态转移方程。

1.确定状态:

因为我们需要切割木块以获得最大收益,所以状态用木块的尺寸表示,即木块的高度和宽度。定义一个二维数组 dp,其中 dp[i][j] 表示切割一个大小为 i x j 的木块后能得到的最大收益。

2.确定状态转移方程:

对于尺寸为(x,y)的木块,考虑三种情况:

        如果数组 prices 中存在 (x,y,price) 这一三元组,表示可以以 price 的价格卖出一个高为 x、宽为 y 的矩形木块,则状态转移方程为:

dp[x][y] = price

        如果 x > 1,那么可以沿水平方向将木块切割成两部分,它们的高分别是 ix - i,宽为 y。状态转移方程为:

 dp[x][y] = max(dp[i][y] + dp[x - i][y] for i in range(1, x))

        如果 y > 1,那么可以沿垂直方向将木块切割成两部分,它们的宽分别是 jy - j,高为 x。状态转移方程为:

 dp[x][y] = max(dp[x][j] + dp[x][y - j] for j in range(1, y))

代码如下:

class Solution(object):
    def sellingWood(self, m, n, prices):
        """
        :type m: int
        :type n: int
        :type prices: List[List[int]]
        :rtype: int
        """
        # 构建哈希映射,键为木块的尺寸 (hi, wi),值为对应价格
        price_map = {}
        for hi, wi, price in prices:
            price_map[(hi, wi)] = price

        # 定义动态规划数组,dp[x][y]表示木块高为x、宽为y时的最大收益
        dp = [[0] * (n + 1) for _ in range(m + 1)]

        # 遍历每个可能的木块尺寸
        for x in range(1, m + 1):
            for y in range(1, n + 1):
                # 第一种情况:如果有对应的价格,直接取得最大收益
                if (x, y) in price_map:
                    dp[x][y] = price_map[(x, y)]
                # 第二种情况:沿水平方向切割木块
                for i in range(1, x):
                    dp[x][y] = max(dp[x][y], dp[i][y] + dp[x - i][y])
                # 第三种情况:沿垂直方向切割木块
                for j in range(1, y):
                    dp[x][y] = max(dp[x][y], dp[x][j] + dp[x][y - j])

        return dp[m][n]

运行通过:

 动态规划早就忘干净了...感谢gpt帮我想起来 ^_^

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值