Давайте начнем с примера. Предположим, что N=5 и k=3(при условии, что после деления будет три части). Пусть наш массив будет {1,2,8,4,9}. Мы можем заметить, что если k было равно 1, то сумма максимального раздела была бы суммой (все элементы массива), т.е. 24, а если k=5, то сумма максимальный раздел будет max(все элементы массива), т. е. 9. Теперь мы можем наблюдать, что по мере увеличения k сумма минимального значения максимального раздела уменьшается. В этом наш алгоритм воспользуется помощью бинарного поиска. Но как это сделать????? Глядя на вопрос, мы видим, что мы должны найти минимум максимума, который вызывает ощущение проблем типа «FFFFTTTTTTTT», где мы должны найти первое T. Мы собираемся сделать то же самое, но возьмем помощь функции в этом. (Посмотрите на код и ответьте здесь, параллельно). Вспомогательная функция найдет значение K, когда будет предоставлена минимальная сумма максимального раздела. Мы инициализируем low = max (все элементы массива), здесь low=9 и high=sum(все элементы массива), т.е. high=24. Следовательно, mid=16, поэтому для min_max_dist=16 наша вспомогательная функция вернет необходимое количество k. k>K, это означает, что наш min_max_dist может вместить больше значений. Таким образом, мы увеличим наше минимальное значение до mid+1, и если количество k‹=K , это означает, что при меньшем количестве разделов мы можем достичь этого min_max_dist, но мы можем сделать больше разделов и, следовательно, мы можем уменьшить высокое значение до среднего. Итак, наш код будет выполняться в нашем примере в следующем примере. путь:-
low high mid number_of_k
9 24 16 9
9 16 12 2
9 12 10 4
11 12 11 3
и, наконец, будет возвращен наш результат->low=11..
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
ll number_of_k(ll arr[],ll n,ll minimum_max__dist){
ll sum=0;
ll k=1;
for(ll i=0;i<n;i++){
sum+=arr[i];
if(sum > minimum_max__dist){
sum=arr[i];
k++;
}
}
return k;
}
ll Max(ll arr[], ll n)
{
ll max1 = -1;
for (ll i = 0; i < n; i++)
if (arr[i] > max1)
max1 = arr[i];
return max1;
}
ll Sum(ll arr[], ll n)
{
ll sum = 0;
for (int i = 0; i < n; i++)
sum += arr[i];
return sum;
}
ll min_max_bin_search(ll arr[],ll n,ll k){
ll low=Max(arr,n);
ll high=Sum(arr,n);
ll mid;
while(low<high){
mid=low+(high-low)/2;
if(number_of_k(arr,n,mid)<=k)
high=mid;
else
low=mid+1;
}
return low;
}
int main()
{
ll n,k;
cin>>n>>k;
ll arr[n];
for(ll i=0;i<n;i++)cin>>arr[i];
cout<<min_max_bin_search(arr,n,k)<<endl;
return 0;
}
Временная сложность этого алгоритма равна->O(nlogn)
Прочтите эту статью о двоичном поиске-> https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/ и решить эту проблему-> http://www.spoj.com/problems/AGGRCOW/
09.06.2018