Dynamic programming. Make an array
int best[k+1][n+1];
where best[i][j] is the best that can be achieved by breaking the first j elements of the int i subarrays array. best[1][j] is just the sum of the first elements of j . Having row i , you calculate row i+1 as follows:
for(j = i+1; j <= n; ++j){ temp = min(best[i][i], arraysum[i+1 .. j]); for(h = i+1; h < j; ++h){ if (min(best[i][h], arraysum[h+1 .. j]) < temp){ temp = min(best[i][h], arraysum[h+1 .. j]); } } best[i+1][j] = temp; }
best[m][n] will contain the solution. Algorithm O (n ^ 2 * k), maybe something better.
Edit: a combination of the ideas of ChingPing, toto2, Coffee on Mars and rds (in the order in which they appear when I see this page at the moment).
Set A = ceiling(sum/k) . This is a minimum minimum estimate. To find a good upper bound for a minimum, create a good section in any of the above ways, moving the borders until you find some simple move that will reduce the maximum dose anyway. This gives you an upper bound B, not much larger than a lower bound (if it were much larger, you would have found a slight improvement by moving the bound, I think). Now let's start the ChingPing algorithm, with a known upper bound, reducing the number of possible branches. This last phase is O ((BA) * n), finding B unknown, but I think it is better than O (n ^ 2).
source share