- 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
- 144 lines of Python from the credited upstream file minimum-possible-maximum-waiting-time.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 minMaxWaitingTime(self, demand, fuel):7 """8 :type demand: List[int]9 :type fuel: List[int]10 :rtype: int11 """12 FULLMASK = ((1<<64)-1)13 def binary_search(left, right, check):14 while left <= right:15 mid = left+(right-left)216 if check(mid):17 right = mid-118 else:19 left = mid+120 return left21 22 def low(x):23 return FULLMASK if x >= 63 else ((1<<(x+1))-1) if x >= 0 else 024 25 def high(x):26 return FULLMASK^low(x-1)27 28 def find_max_served():29 mask = 130 total = 031 for i, x in enumerate(demand):32 mask = ((mask<<x)&low(fuel[0]))|(mask&high(total+x-fuel[1]))33 if not mask:34 return i35 total += x36 return len(demand)37 38 def check(w):39 def update(last, gap, mask):40 if last == 0:41 mask = (mask<<demand[i])&low(fuel[0])42 else:43 mask &= high(total+demand[i]-fuel[1])44 new_dp[last][gap] |= mask45 46 47 48 49 50 dp = [[0]*(mx+1) for _ in xrange(2)]51 dp[0][0] = 152 total = 053 for i in xrange(l):54 new_dp = [[0]*(mx+1) for _ in xrange(2)]55 for last in xrange(len(dp)):56 for gap in xrange(len(dp[0])):57 if not dp[last][gap]:58 continue59 if (demand[i-1] if i-1 >= 0 else 0) <= w:60 update(last, max(gap-(demand[i-1] if i-1 >= 0 else 0), 0), dp[last][gap])61 if gap <= w:62 update(last^1, max((demand[i-1] if i-1 >= 0 else 0)-gap, 0), dp[last][gap])63 dp = new_dp64 total += demand[i]65 return any(x for row in dp for x in row)66 67 l = find_max_served()68 mx = max(demand)69 return binary_search(0, mx, check) if l else -170 71 72737475class Solution2(object):76 def minMaxWaitingTime(self, demand, fuel):77 """78 :type demand: List[int]79 :type fuel: List[int]80 :rtype: int81 """82 def binary_search(left, right, check):83 while left <= right:84 mid = left+(right-left)285 if check(mid):86 right = mid-187 else:88 left = mid+189 return left90 91 def find_max_served():92 dp = [False]*(fuel[0]+1) 93 dp[0] = True94 total = 095 for i, x in enumerate(demand):96 new_dp = [False]*(fuel[0]+1)97 for used0 in xrange(len(dp)):98 if not dp[used0]:99 continue100 if used0+x <= fuel[0]:101 new_dp[used0+x] = True102 if (total-used0)+x <= fuel[1]:103 new_dp[used0] = True104 if not any(new_dp):105 return i106 dp = new_dp107 total += x108 return len(demand)109 110 def check(w):111 def update(last, gap, used0):112 if last == 0:113 if used0+demand[i] <= fuel[0]:114 new_dp[last][gap][used0+demand[i]] = True115 else:116 if (total-used0)+demand[i] <= fuel[1]:117 new_dp[last][gap][used0] = True118 119 120 121 122 123 dp = [[[False]*(fuel[0]+1) for _ in xrange(mx+1)] for _ in xrange(2)]124 dp[0][0][0] = True125 total = 0126 for i in xrange(l):127 new_dp = [[[False]*(fuel[0]+1) for _ in xrange(mx+1)] for _ in xrange(2)]128 for last in xrange(len(dp)):129 for gap in xrange(len(dp[0])):130 for used0 in xrange(len(dp[0][0])):131 if not dp[last][gap][used0]:132 continue133 if (demand[i-1] if i-1 >= 0 else 0) <= w:134 update(last, max(gap-(demand[i-1] if i-1 >= 0 else 0), 0), used0)135 if gap <= w:136 update(last^1, max((demand[i-1] if i-1 >= 0 else 0)-gap, 0), used0)137 dp = new_dp138 total += demand[i]139 return any(x for matrix in dp for row in matrix for x in row)140 141 l = find_max_served()142 mx = max(demand)143 return binary_search(0, mx, check) if l else -1144