- Define precisely what one DP state represents.
- Establish the base cases before transitions are evaluated.
- Process states in dependency order and combine only already-known values.
Code notes
- 84 lines of Python from the credited upstream file minimum-time-to-break-locks-i.py.
- The implementation visibly relies on sequence storage, cached states.
- No explicit loop blocks detected.
Complexity
Multiply the number of reachable states by the work performed for each transition, then include the stored state table in memory usage.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 45class Solution(object):6 def findMinimumTime(self, strength, K):7 """8 :type strength: List[int]9 :type K: int10 :rtype: int11 """12 13 14 def hungarian(a): 15 if not a:16 return 0, []17 n, m = len(a)+1, len(a[0])+118 u, v, p, ans = [0]*n, [0]*m, [0]*m, [0]*(n-1)19 for i in xrange(1, n):20 p[0] = i21 j0 = 0 22 dist, pre = [float("inf")]*m, [-1]*m23 done = [False]*(m+1)24 while True: 25 done[j0] = True26 i0, j1, delta = p[j0], None, float("inf")27 for j in xrange(1, m):28 if done[j]:29 continue30 cur = a[i0-1][j-1]-u[i0]-v[j]31 if cur < dist[j]:32 dist[j], pre[j] = cur, j033 if dist[j] < delta:34 delta, j1 = dist[j], j35 for j in xrange(m):36 if done[j]:37 u[p[j]] += delta38 v[j] -= delta39 else:40 dist[j] -= delta41 j0 = j142 if not p[j0]:43 break44 while j0: 45 j1 = pre[j0]46 p[j0], j0 = p[j1], j147 for j in xrange(1, m):48 if p[j]:49 ans[p[j]-1] = j-150 return -v[0], ans 51 52 def ceil_divide(a, b):53 return (a+b-1)b54 55 adj = [[ceil_divide(strength[i], 1+j*K) for j in xrange(len(strength))] for i in xrange(len(strength))]56 return hungarian(adj)[0]57 58 59606162class Solution2(object):63 def findMinimumTime(self, strength, K):64 """65 :type strength: List[int]66 :type K: int67 :rtype: int68 """69 def ceil_divide(a, b):70 return (a+b-1)b71 72 def popcount(x):73 return bin(x).count('1')74 75 dp = [float('inf')]*(1<<len(strength))76 dp[0] = 077 for mask in xrange(1, len(dp)):78 x = 1+(popcount(mask)-1)*K79 for i in xrange(len(strength)):80 if not (mask&(1<<i)):81 continue82 dp[mask] = min(dp[mask], dp[mask^(1<<i)]+ceil_divide(strength[i], x))83 return dp[-1]84