Skip to content

Commit 11eca7f

Browse files
committed
feat: add solutions to lc problem: No.0956
No.0956.Tallest Billboard
1 parent be5b142 commit 11eca7f

File tree

3 files changed

+339
-1
lines changed

3 files changed

+339
-1
lines changed

solution/0900-0999/0956.Tallest Billboard/README.md

+170-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,27 @@
5050

5151
<!-- 这里可写通用的实现逻辑 -->
5252

53-
**方法一:动态规划**
53+
**方法一:记忆化搜索**
54+
55+
我们设计一个函数 $dfs(i, j)$,表示从第 $i$ 根钢筋开始,且当前高度差为 $j$ 时,两边的最大共同高度。那么答案就是 $dfs(0, 0)$。
56+
57+
函数 $dfs(i, j)$ 的计算过程如下:
58+
59+
如果 $i=n$,此时判断 $j$ 是否为 $0$,如果是则返回 $0$,否则返回 $-\infty$。
60+
61+
如果 $i \lt n$,此时有三种情况:
62+
63+
1. 不选择第 $i$ 根钢筋,此时 $dfs(i, j) = dfs(i+1, j)$;
64+
1. 选择第 $i$ 根钢筋,并且放置在原本高度较高的一边,那么 $dfs(i, j) = dfs(i+1, j+rods[i])$;
65+
1. 选择第 $i$ 根钢筋,并且放置在高度较低的一边,此时共同高度增加了 $\min(j, rods[i])$,那么 $dfs(i, j) = dfs(i+1, |rods[i]-j|) + \min(j, rods[i])$。
66+
67+
我们取这三种情况下的最大值,即可得到 $dfs(i, j)$ 的值。
68+
69+
为了避免重复计算,我们使用一个二维数组 $f$ 来记录已经计算过的 $dfs(i, j)$ 的值,调用 $dfs(i, j)$ 时,如果 $f[i][j]$ 已经被计算过,则直接返回 $f[i][j]$。否则,我们计算 $dfs(i, j)$ 的值,并将其存入 $f[i][j]$。
70+
71+
时间复杂度 $O(n \times S)$,空间复杂度 $O(n \times S)$。其中 $n$ 和 $S$ 分别为 $rods$ 的长度和 $rods$ 中所有元素的和。
72+
73+
**方法二:动态规划**
5474

5575
我们定义 $f[i][j]$ 表示前 $i$ 根钢筋,两边高度差为 $j$ 时的最大共同高度。初始时 $f[0][0]=0$,其余 $f[i][j]=-\infty$。我们求出所有 $rods[i]$ 的和,记为 $s$,那么 $j$ 的取值范围为 $[0,..s]$。
5676

@@ -80,6 +100,20 @@ $$
80100

81101
<!-- 这里可写当前语言的特殊实现逻辑 -->
82102

103+
```python
104+
class Solution:
105+
def tallestBillboard(self, rods: List[int]) -> int:
106+
@cache
107+
def dfs(i: int, j: int) -> int:
108+
if i >= len(rods):
109+
return 0 if j == 0 else -inf
110+
ans = max(dfs(i + 1, j), dfs(i + 1, j + rods[i]))
111+
ans = max(ans, dfs(i + 1, abs(rods[i] - j)) + min(j, rods[i]))
112+
return ans
113+
114+
return dfs(0, 0)
115+
```
116+
83117
```python
84118
class Solution:
85119
def tallestBillboard(self, rods: List[int]) -> int:
@@ -105,6 +139,37 @@ class Solution:
105139

106140
<!-- 这里可写当前语言的特殊实现逻辑 -->
107141

142+
```java
143+
class Solution {
144+
private Integer[][] f;
145+
private int[] rods;
146+
private int n;
147+
148+
public int tallestBillboard(int[] rods) {
149+
int s = 0;
150+
for (int x : rods) {
151+
s += x;
152+
}
153+
n = rods.length;
154+
this.rods = rods;
155+
f = new Integer[n][s + 1];
156+
return dfs(0, 0);
157+
}
158+
159+
private int dfs(int i, int j) {
160+
if (i >= n) {
161+
return j == 0 ? 0 : -(1 << 30);
162+
}
163+
if (f[i][j] != null) {
164+
return f[i][j];
165+
}
166+
int ans = Math.max(dfs(i + 1, j), dfs(i + 1, j + rods[i]));
167+
ans = Math.max(ans, dfs(i + 1, Math.abs(rods[i] - j)) + Math.min(j, rods[i]));
168+
return f[i][j] = ans;
169+
}
170+
}
171+
```
172+
108173
```java
109174
class Solution {
110175
public int tallestBillboard(int[] rods) {
@@ -141,6 +206,30 @@ class Solution {
141206

142207
### **C++**
143208

209+
```cpp
210+
class Solution {
211+
public:
212+
int tallestBillboard(vector<int>& rods) {
213+
int s = accumulate(rods.begin(), rods.end(), 0);
214+
int n = rods.size();
215+
int f[n][s + 1];
216+
memset(f, -1, sizeof(f));
217+
function<int(int, int)> dfs = [&](int i, int j) -> int {
218+
if (i >= n) {
219+
return j == 0 ? 0 : -(1 << 30);
220+
}
221+
if (f[i][j] != -1) {
222+
return f[i][j];
223+
}
224+
int ans = max(dfs(i + 1, j), dfs(i + 1, j + rods[i]));
225+
ans = max(ans, dfs(i + 1, abs(j - rods[i])) + min(j, rods[i]));
226+
return f[i][j] = ans;
227+
};
228+
return dfs(0, 0);
229+
}
230+
};
231+
```
232+
144233
```cpp
145234
class Solution {
146235
public:
@@ -173,6 +262,61 @@ public:
173262

174263
### **Go**
175264

265+
```go
266+
func tallestBillboard(rods []int) int {
267+
s := 0
268+
for _, x := range rods {
269+
s += x
270+
}
271+
n := len(rods)
272+
f := make([][]int, n)
273+
for i := range f {
274+
f[i] = make([]int, s+1)
275+
for j := range f[i] {
276+
f[i][j] = -1
277+
}
278+
}
279+
var dfs func(i, j int) int
280+
dfs = func(i, j int) int {
281+
if i >= n {
282+
if j == 0 {
283+
return 0
284+
}
285+
return -(1 << 30)
286+
}
287+
if f[i][j] != -1 {
288+
return f[i][j]
289+
}
290+
ans := max(dfs(i+1, j), dfs(i+1, j+rods[i]))
291+
ans = max(ans, dfs(i+1, abs(j-rods[i]))+min(j, rods[i]))
292+
f[i][j] = ans
293+
return ans
294+
}
295+
return dfs(0, 0)
296+
}
297+
298+
func max(a, b int) int {
299+
if a > b {
300+
return a
301+
}
302+
return b
303+
}
304+
305+
func min(a, b int) int {
306+
if a < b {
307+
return a
308+
}
309+
return b
310+
}
311+
312+
func abs(x int) int {
313+
if x < 0 {
314+
return -x
315+
}
316+
return x
317+
}
318+
```
319+
176320
```go
177321
func tallestBillboard(rods []int) int {
178322
n := len(rods)
@@ -215,6 +359,31 @@ func max(a, b int) int {
215359
}
216360
```
217361

362+
### **TypeScript**
363+
364+
```ts
365+
function tallestBillboard(rods: number[]): number {
366+
const s = rods.reduce((a, b) => a + b, 0);
367+
const n = rods.length;
368+
const f = new Array(n).fill(0).map(() => new Array(s + 1).fill(-1));
369+
const dfs = (i: number, j: number): number => {
370+
if (i >= n) {
371+
return j === 0 ? 0 : -(1 << 30);
372+
}
373+
if (f[i][j] !== -1) {
374+
return f[i][j];
375+
}
376+
let ans = Math.max(dfs(i + 1, j), dfs(i + 1, j + rods[i]));
377+
ans = Math.max(
378+
ans,
379+
dfs(i + 1, Math.abs(j - rods[i])) + Math.min(j, rods[i]),
380+
);
381+
return (f[i][j] = ans);
382+
};
383+
return dfs(0, 0);
384+
}
385+
```
386+
218387
### **...**
219388

220389
```

solution/0900-0999/0956.Tallest Billboard/README_EN.md

+149
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,20 @@
5050

5151
### **Python3**
5252

53+
```python
54+
class Solution:
55+
def tallestBillboard(self, rods: List[int]) -> int:
56+
@cache
57+
def dfs(i: int, j: int) -> int:
58+
if i >= len(rods):
59+
return 0 if j == 0 else -inf
60+
ans = max(dfs(i + 1, j), dfs(i + 1, j + rods[i]))
61+
ans = max(ans, dfs(i + 1, abs(rods[i] - j)) + min(j, rods[i]))
62+
return ans
63+
64+
return dfs(0, 0)
65+
```
66+
5367
```python
5468
class Solution:
5569
def tallestBillboard(self, rods: List[int]) -> int:
@@ -73,6 +87,37 @@ class Solution:
7387

7488
### **Java**
7589

90+
```java
91+
class Solution {
92+
private Integer[][] f;
93+
private int[] rods;
94+
private int n;
95+
96+
public int tallestBillboard(int[] rods) {
97+
int s = 0;
98+
for (int x : rods) {
99+
s += x;
100+
}
101+
n = rods.length;
102+
this.rods = rods;
103+
f = new Integer[n][s + 1];
104+
return dfs(0, 0);
105+
}
106+
107+
private int dfs(int i, int j) {
108+
if (i >= n) {
109+
return j == 0 ? 0 : -(1 << 30);
110+
}
111+
if (f[i][j] != null) {
112+
return f[i][j];
113+
}
114+
int ans = Math.max(dfs(i + 1, j), dfs(i + 1, j + rods[i]));
115+
ans = Math.max(ans, dfs(i + 1, Math.abs(rods[i] - j)) + Math.min(j, rods[i]));
116+
return f[i][j] = ans;
117+
}
118+
}
119+
```
120+
76121
```java
77122
class Solution {
78123
public int tallestBillboard(int[] rods) {
@@ -109,6 +154,30 @@ class Solution {
109154

110155
### **C++**
111156

157+
```cpp
158+
class Solution {
159+
public:
160+
int tallestBillboard(vector<int>& rods) {
161+
int s = accumulate(rods.begin(), rods.end(), 0);
162+
int n = rods.size();
163+
int f[n][s + 1];
164+
memset(f, -1, sizeof(f));
165+
function<int(int, int)> dfs = [&](int i, int j) -> int {
166+
if (i >= n) {
167+
return j == 0 ? 0 : -(1 << 30);
168+
}
169+
if (f[i][j] != -1) {
170+
return f[i][j];
171+
}
172+
int ans = max(dfs(i + 1, j), dfs(i + 1, j + rods[i]));
173+
ans = max(ans, dfs(i + 1, abs(j - rods[i])) + min(j, rods[i]));
174+
return f[i][j] = ans;
175+
};
176+
return dfs(0, 0);
177+
}
178+
};
179+
```
180+
112181
```cpp
113182
class Solution {
114183
public:
@@ -141,6 +210,61 @@ public:
141210

142211
### **Go**
143212

213+
```go
214+
func tallestBillboard(rods []int) int {
215+
s := 0
216+
for _, x := range rods {
217+
s += x
218+
}
219+
n := len(rods)
220+
f := make([][]int, n)
221+
for i := range f {
222+
f[i] = make([]int, s+1)
223+
for j := range f[i] {
224+
f[i][j] = -1
225+
}
226+
}
227+
var dfs func(i, j int) int
228+
dfs = func(i, j int) int {
229+
if i >= n {
230+
if j == 0 {
231+
return 0
232+
}
233+
return -(1 << 30)
234+
}
235+
if f[i][j] != -1 {
236+
return f[i][j]
237+
}
238+
ans := max(dfs(i+1, j), dfs(i+1, j+rods[i]))
239+
ans = max(ans, dfs(i+1, abs(j-rods[i]))+min(j, rods[i]))
240+
f[i][j] = ans
241+
return ans
242+
}
243+
return dfs(0, 0)
244+
}
245+
246+
func max(a, b int) int {
247+
if a > b {
248+
return a
249+
}
250+
return b
251+
}
252+
253+
func min(a, b int) int {
254+
if a < b {
255+
return a
256+
}
257+
return b
258+
}
259+
260+
func abs(x int) int {
261+
if x < 0 {
262+
return -x
263+
}
264+
return x
265+
}
266+
```
267+
144268
```go
145269
func tallestBillboard(rods []int) int {
146270
n := len(rods)
@@ -183,6 +307,31 @@ func max(a, b int) int {
183307
}
184308
```
185309

310+
### **TypeScript**
311+
312+
```ts
313+
function tallestBillboard(rods: number[]): number {
314+
const s = rods.reduce((a, b) => a + b, 0);
315+
const n = rods.length;
316+
const f = new Array(n).fill(0).map(() => new Array(s + 1).fill(-1));
317+
const dfs = (i: number, j: number): number => {
318+
if (i >= n) {
319+
return j === 0 ? 0 : -(1 << 30);
320+
}
321+
if (f[i][j] !== -1) {
322+
return f[i][j];
323+
}
324+
let ans = Math.max(dfs(i + 1, j), dfs(i + 1, j + rods[i]));
325+
ans = Math.max(
326+
ans,
327+
dfs(i + 1, Math.abs(j - rods[i])) + Math.min(j, rods[i]),
328+
);
329+
return (f[i][j] = ans);
330+
};
331+
return dfs(0, 0);
332+
}
333+
```
334+
186335
### **...**
187336

188337
```

0 commit comments

Comments
 (0)