INF = 100000000000000
pickup = {}
dest = {}
trace = {}
dp = {}
def calc(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
def solve(curPos, completed, ongoing):
if len(completed) == N and len(ongoing) == 0:
return 0
curState = (curPos, frozenset(completed), frozenset(ongoing))
if curState in dp.keys():
return dp[curState]
minVal = INF
for i in pickup.keys():
if i in completed: continue
newOngoing = ongoing.copy()
newCompleted = completed.copy()
if i in ongoing:
newOngoing.remove(i)
newCompleted.add(i)
val = calc(curPos, dest[i]) + solve(dest[i], newCompleted, newOngoing)
if val < minVal:
minVal = val
trace[curState] = \
("drop " + str(i), (dest[i], newCompleted, newOngoing))
elif len(ongoing) < maxCustomers:
newOngoing.add(i)
val = calc(curPos, pickup[i]) + solve(pickup[i], newCompleted, newOngoing)
if val < minVal:
minVal = val
trace[curState] = \
("pickup " + str(i), (pickup[i], newCompleted, newOngoing))
dp[curState] = minVal
return minVal
def path(state):
stateVar = (state[0], frozenset(state[1]), frozenset(state[2]))
if stateVar not in trace.keys():
return
print (trace[stateVar][0])
if trace[stateVar][1] != None:
return path(trace[stateVar][1])
maxCustomers = int(input())
rstr = input().split(",")
start = (int(rstr[0]), int(rstr[1]))
N = int(input())
for i in range(N):
line = input().split(",")
pickup[int(line[0])] = (int(line[1]), int(line[2]))
dest[int(line[0])] = (int(line[3]), int(line[4]))
print("Total distance travelled: ", solve(start, set(), set()))
path((start, set(), set()))
SU5GID0gMTAwMDAwMDAwMDAwMDAwCgpwaWNrdXAgPSB7fQpkZXN0ID0ge30KdHJhY2UgPSB7fQpkcCA9IHt9CgpkZWYgY2FsYyhhLCBiKToKCXJldHVybiBhYnMoYVswXSAtIGJbMF0pICsgYWJzKGFbMV0gLSBiWzFdKQoKZGVmIHNvbHZlKGN1clBvcywgY29tcGxldGVkLCBvbmdvaW5nKToKCWlmIGxlbihjb21wbGV0ZWQpID09IE4gYW5kIGxlbihvbmdvaW5nKSA9PSAwOgoJCXJldHVybiAwCgljdXJTdGF0ZSA9IChjdXJQb3MsIGZyb3plbnNldChjb21wbGV0ZWQpLCBmcm96ZW5zZXQob25nb2luZykpCQoJCglpZiBjdXJTdGF0ZSBpbiBkcC5rZXlzKCk6CgkJcmV0dXJuIGRwW2N1clN0YXRlXQoJCQoJbWluVmFsID0gSU5GCglmb3IgaSBpbiBwaWNrdXAua2V5cygpOgoJCWlmIGkgaW4gY29tcGxldGVkOiBjb250aW51ZQoJCW5ld09uZ29pbmcgPSBvbmdvaW5nLmNvcHkoKQoJCW5ld0NvbXBsZXRlZCA9IGNvbXBsZXRlZC5jb3B5KCkKCgkJaWYgaSBpbiBvbmdvaW5nOgoJCQluZXdPbmdvaW5nLnJlbW92ZShpKQoJCQluZXdDb21wbGV0ZWQuYWRkKGkpCgkJCXZhbCA9IGNhbGMoY3VyUG9zLCBkZXN0W2ldKSArIHNvbHZlKGRlc3RbaV0sIG5ld0NvbXBsZXRlZCwgbmV3T25nb2luZykKCQkJaWYgdmFsIDwgbWluVmFsOgoJCQkJbWluVmFsID0gdmFsCgkJCQl0cmFjZVtjdXJTdGF0ZV0gPSBcCgkJCQkJKCJkcm9wICIgKyBzdHIoaSksIChkZXN0W2ldLCBuZXdDb21wbGV0ZWQsIG5ld09uZ29pbmcpKQoJCWVsaWYgbGVuKG9uZ29pbmcpIDwgbWF4Q3VzdG9tZXJzOgoJCQluZXdPbmdvaW5nLmFkZChpKQoJCQl2YWwgPSBjYWxjKGN1clBvcywgcGlja3VwW2ldKSArIHNvbHZlKHBpY2t1cFtpXSwgbmV3Q29tcGxldGVkLCBuZXdPbmdvaW5nKQoJCQlpZiB2YWwgPCBtaW5WYWw6CgkJCQltaW5WYWwgPSB2YWwKCQkJCXRyYWNlW2N1clN0YXRlXSA9IFwKCQkJCQkoInBpY2t1cCAiICsgc3RyKGkpLCAocGlja3VwW2ldLCBuZXdDb21wbGV0ZWQsIG5ld09uZ29pbmcpKQoJCglkcFtjdXJTdGF0ZV0gPSBtaW5WYWwKCXJldHVybiBtaW5WYWwKCmRlZiBwYXRoKHN0YXRlKToKCXN0YXRlVmFyID0gKHN0YXRlWzBdLCBmcm96ZW5zZXQoc3RhdGVbMV0pLCBmcm96ZW5zZXQoc3RhdGVbMl0pKQoJaWYgc3RhdGVWYXIgbm90IGluIHRyYWNlLmtleXMoKToKCQlyZXR1cm4KCXByaW50ICh0cmFjZVtzdGF0ZVZhcl1bMF0pCglpZiB0cmFjZVtzdGF0ZVZhcl1bMV0gIT0gTm9uZTogCgkJcmV0dXJuIHBhdGgodHJhY2Vbc3RhdGVWYXJdWzFdKQoJCQkJCm1heEN1c3RvbWVycyA9IGludChpbnB1dCgpKQpyc3RyID0gaW5wdXQoKS5zcGxpdCgiLCIpCnN0YXJ0ID0gKGludChyc3RyWzBdKSwgaW50KHJzdHJbMV0pKQpOID0gaW50KGlucHV0KCkpCmZvciBpIGluIHJhbmdlKE4pOgoJbGluZSA9IGlucHV0KCkuc3BsaXQoIiwiKQoJcGlja3VwW2ludChsaW5lWzBdKV0gPSAoaW50KGxpbmVbMV0pLCBpbnQobGluZVsyXSkpCglkZXN0W2ludChsaW5lWzBdKV0gPSAoaW50KGxpbmVbM10pLCBpbnQobGluZVs0XSkpCgpwcmludCgiVG90YWwgZGlzdGFuY2UgdHJhdmVsbGVkOiAiLCBzb2x2ZShzdGFydCwgc2V0KCksIHNldCgpKSkKcGF0aCgoc3RhcnQsIHNldCgpLCBzZXQoKSkpCgkJCg==
NgoxNDgsMTI4CjcKMSw0NSwxOTksMTc4LDY5CjIsNTQsODcsMjYsODMKMywxOTcsMTQ3LDEzNSw5Mwo0LDEyLDQ5LDYxLDY2CjUsOTEsOCw1NSw3Mwo2LDg4LDQyLDE1LDkKNywxODQsMTQ0LDMxLDM0
6
148,128
7
1,45,199,178,69
2,54,87,26,83
3,197,147,135,93
4,12,49,61,66
5,91,8,55,73
6,88,42,15,9
7,184,144,31,34