If we can make a function that can check if a given maximum can be achieved, then we can find the solution using binary search on the maximum. (each time the maximum is achievable, decrease it, if it's not achievable, increase it).
the checking function might look like this:
def check(array, M, i, j, max)
this will return true if it's possible to reduce everything between i and j to below max with M cost. We start of with i=0, j=len(array), max=max_guess
you now have many options of what to do inside check. you might try:
possible = check(M/2, i..i+j/2, ..) and check(M/2, i..i+j/2,..)
return possible
however splitting M into both halves isn't a good idea because one half may require more. Perhaps you could use binary search to determine how to split M into the halves. However maybe it's not even possible to split the array into half because some subsections might go over both halves, so perhaps you need to split else where? or perhaps you need to try all combinations of i,j for splitting.
Good luck.