Giả sử chúng ta có một danh sách các số được gọi là num và một giá trị khác là k. Chúng ta có thể chia danh sách thành k danh sách con không rỗng. Chúng ta phải tìm tổng lớn nhất nhỏ nhất của k danh sách con.
Vì vậy, nếu đầu vào là nums =[2, 4, 3, 5, 12] k =2, thì đầu ra sẽ là 14, vì chúng ta có thể chia danh sách như:[2, 4, 3, 5] và [ 12].
Để giải quyết vấn đề này, chúng tôi sẽ làm theo các bước sau -
-
Xác định một hàm ok (), điều này sẽ lấy mảng v, k, x,
-
cnt:=0, sum:=0
-
cho mỗi phần tử tôi trong v -
-
nếu sum + i> x thì -
-
sum:=i
-
(tăng cnt lên 1)
-
-
Nếu không
-
sum:=sum + i
-
-
-
trả về true khi cnt <=k, ngược lại là false
-
Từ phương thức chính, hãy làm như sau -
-
thấp:=0, ret:=0, cao:=0
-
cho mỗi phần tử tôi trong nums
-
high:=high + i
-
ret:=ret + i
-
thấp:=tối đa của thấp và i
-
-
trong khi thấp <=cao, làm -
-
giữa:=low + (cao - thấp) / 2
-
nếu ok (nums, k - 1, mid) là true, thì -
-
ret:=mid
-
cao:=mid - 1
-
-
Nếu không
-
thấp:=mid + 1
-
-
-
trả lại ret
Ví dụ
Hãy cùng chúng tôi xem cách triển khai sau để hiểu rõ hơn -
#include <bits/stdc++.h>
using namespace std;
bool ok(vector <int>& v, int k, int x){
int cnt = 0;
int sum = 0;
for(int i : v){
if(sum + i > x){
sum = i;
cnt++;
}
else{
sum += i;
}
}
return cnt <= k;
}
int solve(vector<int>& nums, int k) {
int low = 0;
int ret = 0;
int high = 0;
for(int i : nums){
high += i;
ret += i;
low = max(low, i);
}
while(low <= high){
int mid = low + ( high - low) / 2;
if(ok(nums, k - 1, mid)){
ret = mid;
high = mid - 1;
}
else{
low = mid + 1;
}
}
return ret;
}
int main(){
vector<int> v = {2, 4, 3, 5, 12};
int k = 2;
cout << solve(v, k);
} Đầu vào
{2, 4, 3, 5, 12}, 2 Đầu ra
14