HackerRank "Angry Children 2"

Fun one! A combination of Greedy and DP. The solution sparkled in my mind - I almost lost it..

Greedy: we sort the input numbers and always pick k continuous numbers - can be proved using contradiction
DP: Visualize it in your mind and you will get it : ) Just like a 2D geometry drawing.

# Get Input
n = int(input())
k = int(input())
arr = []
for _ in range(n):
    v = int(input())
    arr.append(v)

# Sort - kinda Greedy: we only pick k continuous nums
arr.sort()

# Step1: calc D of first k nums
d = 0
areaUp = 0
areaDw = 0
for i in range(1, k):
    areaUp += i * (arr[i] - arr[i - 1]) 
    areaDw += arr[i] - arr[0]
    d += areaUp

ret = d
# Step2: go over rest numbers
for i in range(k, n):
    dd = d
    # removing areaDw
    dd -= areaDw
    areaDw -= (k - 1) * (arr[i - k + 1] - arr[i - k])
    areaDw += arr[i] - arr[i - k + 1]
    # adding new areaUp
    areaUp = areaUp - (arr[i - 1] - arr[i - k]) + (k - 1) * (arr[i] - arr[i - 1])
    dd += areaUp
    d = dd
    ret = min(ret, d)                                 

print(ret)
原文地址:https://www.cnblogs.com/tonix/p/5395104.html