forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
maximum-cost-of-trip-with-k-highways.py
75 lines (70 loc) · 2.37 KB
/
maximum-cost-of-trip-with-k-highways.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
# Time: O(n^2 * 2^n)
# Space: O(n * 2^n)
import itertools
# combination based dp
class Solution(object):
def maximumCost(self, n, highways, k):
"""
:type n: int
:type highways: List[List[int]]
:type k: int
:rtype: int
"""
if k+1 > n: # optionally optimize
return -1
adj = [[] for _ in xrange(n)]
for c1, c2, t in highways:
adj[c1].append((c2, t))
adj[c2].append((c1, t))
result = -1 if k != 1 else 0
dp = [[0, []] for _ in xrange((1<<n))]
for i in xrange(n):
dp[1<<i][1].append(i)
for cnt in xrange(1, n+1):
for choice in itertools.combinations(xrange(n), cnt):
mask = reduce(lambda x, y:x|(1<<y), choice, 0)
total, lasts = dp[mask]
for u in lasts:
for v, t in adj[u]:
if mask&(1<<v):
continue
new_mask = mask|(1<<v)
if total+t < dp[new_mask][0]:
continue
if total+t == dp[new_mask][0]:
dp[new_mask][1].append(v)
continue
dp[new_mask][0] = total+t
dp[new_mask][1] = [v]
if bin(mask).count('1') == k:
result = max(result, dp[new_mask][0])
return result
# Time: O(n^2 * 2^n)
# Space: O(n * 2^n)
# bfs based dp
class Solution2(object):
def maximumCost(self, n, highways, k):
"""
:type n: int
:type highways: List[List[int]]
:type k: int
:rtype: int
"""
if k+1 > n: # required to optimize, otherwise, TLE or MLE
return -1
adj = [[] for _ in xrange(n)]
for c1, c2, t in highways:
adj[c1].append((c2, t))
adj[c2].append((c1, t))
result = -1
dp = [(u, 1<<u, 0) for u in xrange(n)]
while dp:
new_dp = []
for u, mask, total in dp:
if bin(mask).count('1') == k+1:
result = max(result, total)
for v, t in adj[u]:
if mask&(1<<v) == 0:
new_dp.append((v, mask|(1<<v), total+t))
dp = new_dp
return result