区间dp,记忆化搜索,LeetCode 2312. 卖木头块

文章讲述了如何使用区间DP方法解决一个涉及矩形木块切割和售卖的问题,通过定义状态并进行横切和纵切的子状态转移,实现O(n^3)的时间复杂度和O(n^2)的空间复杂度求解策略。
摘要由CSDN通过智能技术生成

一、题目

1、题目描述

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

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

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

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

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

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

2、接口描述

class Solution {
public:
    long long sellingWood(int m, int n, vector<vector<int>>& prices) {
        
    }
};

3、原题链接

2312. 卖木头块


二、解题报告

1、思路分析

关于区间dp,详见:区间DP详解,思路分析,OJ详解-CSDN博客

定义f[l][r]为l × r的矩形的最大收益
那么横切纵切都会有若干子状态,分别由两种切法的子状态转移即可
O(n)转移,O(n^2)状态数,总体O(n^3)的区间dp

2、复杂度

时间复杂度: O(n^3)空间复杂度:O(n^2)

3、代码详解

class Solution {
public:
long long f[205][205];
    long long sellingWood(int m, int n, vector<vector<int>>& prices) {
        unordered_map<int, int> mp;
        for(auto& p : prices) 
            mp[p[0] << 8 | p[1]] = max(p[2], mp[p[0] << 8 | p[1]]);
        memset(f, -1, sizeof f);
        function<long long(int, int)> dfs = [&](int l, int r)->long long{
            if(l <= 0 || r <= 0) return 0;
            if(~f[l][r]) return f[l][r];
            long long& res = f[l][r] = 0;
            if(mp.count(l << 8 | r)) res = mp[l << 8 | r];
            for(int i = 1; i < l; i++)
                res = max(res, dfs(i, r) + dfs(l - i, r));
            for(int i = 1; i < r; i++)
                res = max(res, dfs(l, i) + dfs(l, r - i));
            return res;
        };
        return dfs(m, n);
    }
};

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EQUINOX1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值