-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathtallest-billboard.py
107 lines (86 loc) · 3.51 KB
/
tallest-billboard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from collections import defaultdict
from functools import lru_cache
class Solution:
def tallestBillboardBottomUp2(self, rods: List[int]) -> int:
max_sum = sum(rods) // 2
dp = [[-1] * (max_sum + 1) for _ in range(max_sum + 1)]
dp[0][0] = 0
for rod in range(len(rods)):
for left in range(max_sum + 1):
for right in range(left, max_sum + 1):
if dp[left][right] == rod:
dp[left][right] = rod + 1
if (
left + rods[rod] <= max_sum
and dp[left + rods[rod]][right] != rod
):
dp[left + rods[rod]][right] = rod + 1
if (
right + rods[rod] <= max_sum
and dp[left][right + rods[rod]] != rod
):
dp[left][right + rods[rod]] = rod + 1
for cur_sum in reversed(range(max_sum + 1)):
if dp[cur_sum][cur_sum] > 0:
return cur_sum
return 0
def tallestBillboardBottomUp1(self, rods: List[int]) -> int:
max_len = sum(rods) // 2 + 1
dp = [defaultdict(dict) for _ in range(len(rods) + 1)]
dp[0][0][0] = True
for rod in range(len(rods)):
for left in dp[rod].keys():
for right in dp[rod][left].keys():
if left <= max_len and right <= max_len:
dp[rod + 1][left][right] = True
dp[rod + 1][left + rods[rod]][right] = True
dp[rod + 1][-(left + rods[rod])][right] = True
dp[rod + 1][left][right + rods[rod]] = True
result = 0
for left in dp[-1].keys():
for right in dp[-1][left].keys():
if left == right:
result = max(result, left)
return result
def tallestBillboard(self, rods: List[int]) -> int:
max_sum = sum(rods) // 2 + 1
dp = defaultdict(int)
dp[0] = 0
for rod in range(len(rods)):
dp_new = defaultdict(int)
for total in dp:
dp_new[total] = max(dp_new[total], dp[total])
dp_new[total - rods[rod]] = max(dp_new[total - rods[rod]], dp[total])
dp_new[total + rods[rod]] = max(
dp_new[total + rods[rod]], dp[total] + rods[rod]
)
dp = dp_new
return dp[0]
def tallestBillboardTopDownFast(self, rods: List[int]) -> int:
@lru_cache(None)
def dfs(rod: int, total: int) -> int:
if rod == len(rods):
if total == 0:
return 0
else:
return float("-inf")
return max(
dfs(rod + 1, total),
dfs(rod + 1, total + rods[rod]) + rods[rod],
dfs(rod + 1, total - rods[rod]),
)
return dfs(0, 0)
def tallestBillboardTopDown(self, rods: List[int]) -> int:
@lru_cache(None)
def dfs(rod: int, left: int, right: int) -> int:
if rod == len(rods):
if left == right:
return left
else:
return 0
return max(
dfs(rod + 1, left + rods[rod], right),
dfs(rod + 1, left, right + rods[rod]),
dfs(rod + 1, left, right),
)
return dfs(0, 0, 0)