我心思这题也不难啊,怎么看题解大家都写了这么大一坨(❁´◡`❁)
题面描述
大致意思是给你一个 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 1≤m,n≤200,1≤prices.size≤2×104,1≤pricei≤1×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)=max1≤k<w{
f
(
w
−
k
,
h
)
f(w - k, h)
f(w−k,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)=max1≤k<h{
f
(
w
,
h
−
k
)
f(w, h-k)
f(w,h−k),
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
作者能力有限,如果有任何错误之处,还请各位指教。(~ ̄▽ ̄)~