Skip to content

Commit 0c15c15

Browse files
committed
feat: add solutions to lc problem: No.0956
No.0956.Tallest Billboard
1 parent 695de0f commit 0c15c15

File tree

6 files changed

+387
-2
lines changed

6 files changed

+387
-2
lines changed

Diff for: solution/0900-0999/0956.Tallest Billboard/README.md

+148-1
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,169 @@
5050

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

53+
**方法一:动态规划**
54+
55+
我们定义 $f[i][j]$ 表示前 $i$ 根钢筋,两边高度差为 $j$ 时的最大共同高度。初始时 $f[0][0]=0$,其余 $f[i][j]=-\infty$。我们求出所有 $rods[i]$ 的和,记为 $s$,那么 $j$ 的取值范围为 $[0,..s]$。
56+
57+
对于第 $i$ 根钢筋,我们可以不选择它,此时 $f[i][j]=f[i-1][j]$;也可以选择它,此时有三种情况:
58+
59+
1. 放置在原本高度较高的一边,即满足 $j \geq rods[i-1]$,此时 $f[i][j] = max(f[i][j], f[i-1][j-rods[i-1]])$;
60+
1. 放置在原本高度较低的一遍,如果满足 $j + rods[i-1] \leq s$,此时 $f[i][j] = max(f[i][j], f[i-1][j+rods[i-1]] + rods[i-1])$;如果满足 $j \lt rods[i-1]$,此时 $f[i][j] = max(f[i][j], f[i-1][rods[i-1]-j] + rods[i-1]-j)$。
61+
62+
综上,我们可以得到状态转移方程:
63+
64+
$$
65+
\begin{aligned}
66+
f[i][j] &= f[i-1][j] \\
67+
f[i][j] &= max(f[i][j], f[i-1][j-rods[i-1]]) & \text{if } j \geq rods[i-1] \\
68+
f[i][j] &= max(f[i][j], f[i-1][j+rods[i-1]] + rods[i-1]) & \text{if } j + rods[i-1] \leq s \\
69+
f[i][j] &= max(f[i][j], f[i-1][rods[i-1]-j] + rods[i-1]-j) & \text{if } j \lt rods[i-1]
70+
\end{aligned}
71+
$$
72+
73+
最终答案即为 $f[n][0]$。
74+
75+
时间复杂度 $O(n \times S)$,空间复杂度 $O(n \times S)$。其中 $n$ 和 $S$ 分别为 $rods$ 的长度和 $rods$ 中所有元素的和。
76+
5377
<!-- tabs:start -->
5478

5579
### **Python3**
5680

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

5983
```python
60-
84+
class Solution:
85+
def tallestBillboard(self, rods: List[int]) -> int:
86+
n = len(rods)
87+
s = sum(rods)
88+
f = [[-inf] * (s + 1) for _ in range(n + 1)]
89+
f[0][0] = 0
90+
t = 0
91+
for i, x in enumerate(rods, 1):
92+
t += x
93+
for j in range(t + 1):
94+
f[i][j] = f[i - 1][j]
95+
if j >= x:
96+
f[i][j] = max(f[i][j], f[i - 1][j - x])
97+
if j + x <= t:
98+
f[i][j] = max(f[i][j], f[i - 1][j + x] + x)
99+
if j < x:
100+
f[i][j] = max(f[i][j], f[i - 1][x - j] + x - j)
101+
return f[n][0]
61102
```
62103

63104
### **Java**
64105

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

67108
```java
109+
class Solution {
110+
public int tallestBillboard(int[] rods) {
111+
int n = rods.length;
112+
int s = 0;
113+
for (int x : rods) {
114+
s += x;
115+
}
116+
int[][] f = new int[n + 1][s + 1];
117+
for (var e : f) {
118+
Arrays.fill(e, -(1 << 30));
119+
}
120+
f[0][0] = 0;
121+
for (int i = 1, t = 0; i <= n; ++i) {
122+
int x = rods[i - 1];
123+
t += x;
124+
for (int j = 0; j <= t; ++j) {
125+
f[i][j] = f[i - 1][j];
126+
if (j >= x) {
127+
f[i][j] = Math.max(f[i][j], f[i - 1][j - x]);
128+
}
129+
if (j + x <= t) {
130+
f[i][j] = Math.max(f[i][j], f[i - 1][j + x] + x);
131+
}
132+
if (j < x) {
133+
f[i][j] = Math.max(f[i][j], f[i - 1][x - j] + x - j);
134+
}
135+
}
136+
}
137+
return f[n][0];
138+
}
139+
}
140+
```
141+
142+
### **C++**
143+
144+
```cpp
145+
class Solution {
146+
public:
147+
int tallestBillboard(vector<int>& rods) {
148+
int n = rods.size();
149+
int s = accumulate(rods.begin(), rods.end(), 0);
150+
int f[n + 1][s + 1];
151+
memset(f, -0x3f, sizeof(f));
152+
f[0][0] = 0;
153+
for (int i = 1, t = 0; i <= n; ++i) {
154+
int x = rods[i - 1];
155+
t += x;
156+
for (int j = 0; j <= t; ++j) {
157+
f[i][j] = f[i - 1][j];
158+
if (j >= x) {
159+
f[i][j] = max(f[i][j], f[i - 1][j - x]);
160+
}
161+
if (j + x <= t) {
162+
f[i][j] = max(f[i][j], f[i - 1][j + x] + x);
163+
}
164+
if (j < x) {
165+
f[i][j] = max(f[i][j], f[i - 1][x - j] + x - j);
166+
}
167+
}
168+
}
169+
return f[n][0];
170+
}
171+
};
172+
```
68173
174+
### **Go**
175+
176+
```go
177+
func tallestBillboard(rods []int) int {
178+
n := len(rods)
179+
s := 0
180+
for _, x := range rods {
181+
s += x
182+
}
183+
f := make([][]int, n+1)
184+
for i := range f {
185+
f[i] = make([]int, s+1)
186+
for j := range f[i] {
187+
f[i][j] = -(1 << 30)
188+
}
189+
}
190+
f[0][0] = 0
191+
for i, t := 1, 0; i <= n; i++ {
192+
x := rods[i-1]
193+
t += x
194+
for j := 0; j <= t; j++ {
195+
f[i][j] = f[i-1][j]
196+
if j >= x {
197+
f[i][j] = max(f[i][j], f[i-1][j-x])
198+
}
199+
if j+x <= t {
200+
f[i][j] = max(f[i][j], f[i-1][j+x]+x)
201+
}
202+
if j < x {
203+
f[i][j] = max(f[i][j], f[i-1][x-j]+x-j)
204+
}
205+
}
206+
}
207+
return f[n][0]
208+
}
209+
210+
func max(a, b int) int {
211+
if a > b {
212+
return a
213+
}
214+
return b
215+
}
69216
```
70217

71218
### **...**

Diff for: solution/0900-0999/0956.Tallest Billboard/README_EN.md

+124-1
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,136 @@
5151
### **Python3**
5252

5353
```python
54-
54+
class Solution:
55+
def tallestBillboard(self, rods: List[int]) -> int:
56+
n = len(rods)
57+
s = sum(rods)
58+
f = [[-inf] * (s + 1) for _ in range(n + 1)]
59+
f[0][0] = 0
60+
t = 0
61+
for i, x in enumerate(rods, 1):
62+
t += x
63+
for j in range(t + 1):
64+
f[i][j] = f[i - 1][j]
65+
if j >= x:
66+
f[i][j] = max(f[i][j], f[i - 1][j - x])
67+
if j + x <= t:
68+
f[i][j] = max(f[i][j], f[i - 1][j + x] + x)
69+
if j < x:
70+
f[i][j] = max(f[i][j], f[i - 1][x - j] + x - j)
71+
return f[n][0]
5572
```
5673

5774
### **Java**
5875

5976
```java
77+
class Solution {
78+
public int tallestBillboard(int[] rods) {
79+
int n = rods.length;
80+
int s = 0;
81+
for (int x : rods) {
82+
s += x;
83+
}
84+
int[][] f = new int[n + 1][s + 1];
85+
for (var e : f) {
86+
Arrays.fill(e, -(1 << 30));
87+
}
88+
f[0][0] = 0;
89+
for (int i = 1, t = 0; i <= n; ++i) {
90+
int x = rods[i - 1];
91+
t += x;
92+
for (int j = 0; j <= t; ++j) {
93+
f[i][j] = f[i - 1][j];
94+
if (j >= x) {
95+
f[i][j] = Math.max(f[i][j], f[i - 1][j - x]);
96+
}
97+
if (j + x <= t) {
98+
f[i][j] = Math.max(f[i][j], f[i - 1][j + x] + x);
99+
}
100+
if (j < x) {
101+
f[i][j] = Math.max(f[i][j], f[i - 1][x - j] + x - j);
102+
}
103+
}
104+
}
105+
return f[n][0];
106+
}
107+
}
108+
```
109+
110+
### **C++**
111+
112+
```cpp
113+
class Solution {
114+
public:
115+
int tallestBillboard(vector<int>& rods) {
116+
int n = rods.size();
117+
int s = accumulate(rods.begin(), rods.end(), 0);
118+
int f[n + 1][s + 1];
119+
memset(f, -0x3f, sizeof(f));
120+
f[0][0] = 0;
121+
for (int i = 1, t = 0; i <= n; ++i) {
122+
int x = rods[i - 1];
123+
t += x;
124+
for (int j = 0; j <= t; ++j) {
125+
f[i][j] = f[i - 1][j];
126+
if (j >= x) {
127+
f[i][j] = max(f[i][j], f[i - 1][j - x]);
128+
}
129+
if (j + x <= t) {
130+
f[i][j] = max(f[i][j], f[i - 1][j + x] + x);
131+
}
132+
if (j < x) {
133+
f[i][j] = max(f[i][j], f[i - 1][x - j] + x - j);
134+
}
135+
}
136+
}
137+
return f[n][0];
138+
}
139+
};
140+
```
60141
142+
### **Go**
143+
144+
```go
145+
func tallestBillboard(rods []int) int {
146+
n := len(rods)
147+
s := 0
148+
for _, x := range rods {
149+
s += x
150+
}
151+
f := make([][]int, n+1)
152+
for i := range f {
153+
f[i] = make([]int, s+1)
154+
for j := range f[i] {
155+
f[i][j] = -(1 << 30)
156+
}
157+
}
158+
f[0][0] = 0
159+
for i, t := 1, 0; i <= n; i++ {
160+
x := rods[i-1]
161+
t += x
162+
for j := 0; j <= t; j++ {
163+
f[i][j] = f[i-1][j]
164+
if j >= x {
165+
f[i][j] = max(f[i][j], f[i-1][j-x])
166+
}
167+
if j+x <= t {
168+
f[i][j] = max(f[i][j], f[i-1][j+x]+x)
169+
}
170+
if j < x {
171+
f[i][j] = max(f[i][j], f[i-1][x-j]+x-j)
172+
}
173+
}
174+
}
175+
return f[n][0]
176+
}
177+
178+
func max(a, b int) int {
179+
if a > b {
180+
return a
181+
}
182+
return b
183+
}
61184
```
62185

63186
### **...**
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution {
2+
public:
3+
int tallestBillboard(vector<int>& rods) {
4+
int n = rods.size();
5+
int s = accumulate(rods.begin(), rods.end(), 0);
6+
int f[n + 1][s + 1];
7+
memset(f, -0x3f, sizeof(f));
8+
f[0][0] = 0;
9+
for (int i = 1, t = 0; i <= n; ++i) {
10+
int x = rods[i - 1];
11+
t += x;
12+
for (int j = 0; j <= t; ++j) {
13+
f[i][j] = f[i - 1][j];
14+
if (j >= x) {
15+
f[i][j] = max(f[i][j], f[i - 1][j - x]);
16+
}
17+
if (j + x <= t) {
18+
f[i][j] = max(f[i][j], f[i - 1][j + x] + x);
19+
}
20+
if (j < x) {
21+
f[i][j] = max(f[i][j], f[i - 1][x - j] + x - j);
22+
}
23+
}
24+
}
25+
return f[n][0];
26+
}
27+
};
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
func tallestBillboard(rods []int) int {
2+
n := len(rods)
3+
s := 0
4+
for _, x := range rods {
5+
s += x
6+
}
7+
f := make([][]int, n+1)
8+
for i := range f {
9+
f[i] = make([]int, s+1)
10+
for j := range f[i] {
11+
f[i][j] = -(1 << 30)
12+
}
13+
}
14+
f[0][0] = 0
15+
for i, t := 1, 0; i <= n; i++ {
16+
x := rods[i-1]
17+
t += x
18+
for j := 0; j <= t; j++ {
19+
f[i][j] = f[i-1][j]
20+
if j >= x {
21+
f[i][j] = max(f[i][j], f[i-1][j-x])
22+
}
23+
if j+x <= t {
24+
f[i][j] = max(f[i][j], f[i-1][j+x]+x)
25+
}
26+
if j < x {
27+
f[i][j] = max(f[i][j], f[i-1][x-j]+x-j)
28+
}
29+
}
30+
}
31+
return f[n][0]
32+
}
33+
34+
func max(a, b int) int {
35+
if a > b {
36+
return a
37+
}
38+
return b
39+
}

0 commit comments

Comments
 (0)