# 1674. Minimum Moves to Make Array Complementary - Given n couples - Every person has some number of candy in hand. - Given an positive integer M, everyone can change the number of candy in hand to some value in [1, M]. - Return the minimum number of changes such that all couples have "the same number of candies". M = 4 couple 0: [1, 3] couple 1: [2, 4] answer = 1, 1 + 3 = 2 + (4->2) M = 4 couple 0: [1, 3] couple 1: [4, 4] answer = 2, 1 + 3 = (4->1) + (4->3) ``` M = 10 [1,1], [2,2], [9,9], [10,10] // optimal 4 // fixed 1 couple -> 6 M = 10 [3,5] ->8 range [2,3] [4,7] 8 [9,15] [16,20] changes 2 1 0 1 2 c1=7 c2=7 c3=9 [2, 2M] sol 1: c1 [1, 2] -> c2[4->1, 4->2] +2, c3c2[1, 4->2] -> 3 c2 [4, 4] -> c1+1, c3+2 -> 3 sol2 [3, 5] -> [2, M] dp[2...M] = [22221111011112222] -> c1 = [22221111011111122] -> c2 O(NM) loop (c N) loop (dp M) ``` ```python= # M = 10, [3,5] # range [2,3] [4,7] 8 [9,15] [16,20] # changes 2 1 0 1 2 def findCouple(couples, M): # [2,3] -> [10, 3]=13 or [2, 10]=12 -> max=13 def getUpperBound(c1, c2): poss1 = M + c2 poss2 = c1 + M return max(poss1, poss2) # [2,3] -> [1, 3]=4 or [2, 1]=3 -> min=3 def getLowerBound(c1, c2): poss1 = 1 + c2 poss2 = c1 + 1 return min(poss1, poss2) # step1 init dp = [0]*(2*M+2) # padding # step2 loop couple O(NM) for c1, c2 in couples: sumOfC1C2 = c1 + c2 # [2,3] -> [10, 3]=13 or [2, 10]=12 -> max=13 upperBound = getUpperBound(c1, c2) # [2,3] -> [1, 3]=4 or [2, 1]=3 -> min=3 lowerBound = getLowerBound(c1, c2) dp[2] += 2 dp[lowerBound] -= 1 dp[sumOfC1C2] -= 1 dp[sumOfC1C2+1] += 1 dp[upperBound+1] += 1 # [22221111011111122] """for i in range(1, len(dp)): if sumOfC1C2 == i: continue elif i < lowerBound or i > upperBound: dp[i] += 2 else dp[i] += 1""" ans = inf pre = 0 for n in dp[:2M+1]: pre += n ans = min(ans, pre) return ans # step3 ``` [2 1 1 0 1 1 2 ] -> [2 -1 0 -1 1 0 1 ] 0 l X i i+1 X u+1 2. 1. 1. 0. 1. 1. 2