Динамическое программирование.Создайте массив
int best[k+1][n+1];
, где best[i][j]
- лучшее, что вы можете получить, разбив первые j
элементы массива int i
подмассивы.best[1][j]
- это просто сумма первых j
элементов массива.Имея строку i
, вы вычисляете строку i+1
следующим образом:
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]
будет содержать решение.Алгоритм O (n ^ 2 * k), возможно, возможно что-то лучшее.
Редактировать: комбинация идей ChingPing, toto2, Coffee on Mars и rds (в том порядке, в котором они отображаются, как я сейчассм. эту страницу).
Set A = ceiling(sum/k)
.Это нижняя граница для минимума.Чтобы найти хорошую верхнюю границу для минимума, создайте хороший раздел любым из упомянутых методов, перемещая границы до тех пор, пока не найдете простое движение, которое все еще уменьшает максимальную сумму.Это дает вам верхнюю границу B, не намного большую, чем нижняя граница (если бы она была намного больше, я думаю, вы бы легко достигли улучшения, переместив границу).Теперь перейдем к алгоритму ChingPing, с известной верхней границей, уменьшающей количество возможных ветвей.Эта последняя фаза O ((BA) * n), находка B
неизвестна, но я думаю, что лучше, чем O (n ^ 2).