leetcode2312 卖木头块 题解

我心思这题也不难啊,怎么看题解大家都写了这么大一坨(❁´◡`❁)

题面描述

原来的题面

大致意思是给你一个 n × m n \times m n×m 的长方形木板,然后你每次可以给它一刀,要么是横着一刀要么是竖着一刀,一刀必须切到底(就是每次必须切成两块) 。然后现在可以卖几种不同类型的小木板,不限制卖的木板的数量,给你每种木板的价格和大小,问你靠一开始的木板最多能挣多少钱。

1 ≤ m , n ≤ 200 , 1 ≤ p r i c e s . s i z e ≤ 2 × 1 0 4 , 1 ≤ p r i c e i ≤ 1 × 1 0 6 1 \le m,n \le 200,1 \le prices.size \le 2\times10^4,1\le price_i \le1\times10^6 1m,n200,1prices.size2×104,1pricei1×106(PS:看完题面眉头一皱,看完数据大小没事了)

题解

一眼 dp,首先我们先定义状态,设 f ( w , h ) f(w, h) f(w,h) 是一块 w × h w \times h w×h 的木板最多可以挣多少钱。

因为我们知道每一种木板的价格,所以如果我们可以卖大小为 w i × h i w_i \times h_i wi×hi 的木板,那么我们在一开始就将 f ( w i , h i ) f(w_i, h_i) f(wi,hi) 赋成 p r i c e i price_i pricei (当然这不是最终答案)

然后就是三重循环进行状态转移,从小到大枚举每个状态的模板大小,然后不是每次都切一刀嘛,我们再次枚举对于这个木板下一刀切在哪里,如果有更合适的做法,那么就进行状态转移。

转移方程: f ( w , h ) = max ⁡ 1 ≤ k < w f(w, h) = \mathop{\max}_{1 \le k < w} f(w,h)=max1k<w{ f ( w − k , h ) f(w - k, h) f(wk,h), f ( k , h ) f(k, h) f(k,h)}
f ( w , h ) = max ⁡ 1 ≤ k < h f(w, h) = \mathop{\max}_{1 \le k < h} f(w,h)=max1k<h{ f ( w , h − k ) f(w, h-k) f(w,hk), f ( w , k ) f(w, k) f(w,k)}

代码

class Solution {
public:
    long long sellingWood(int m, int n, vector<vector<int>>& prices) {
        vector<vector<long long> > v(205, vector<long long>(205, 0));
        for (int i = 0; i < prices.size(); i++)
            v[prices[i][0]][prices[i][1]] = prices[i][2];
        for (int h = 1; h <= m; h++)
            for (int w = 1; w <= n; w++)
            {
                for (int k = 1; k < h; k++) // 横着给一刀
                    v[h][w] = max(v[h - k][w] + v[k][w], v[h][w]);
                for (int k = 1; k < w; k++) // 竖着给一刀
                    v[h][w] = max(v[h][w - k] + v[h][k] ,v[h][w]);
            }
        return v[m][n];
    }
};

要是按照我之前打 OI 的尿性我估计我还得压个三四行ヾ(•ω•`)o

运行结果

作者能力有限,如果有任何错误之处,还请各位指教。(~ ̄▽ ̄)~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值