ধরুন আমাদের কাছে সংখ্যার একটি তালিকা আছে যার নাম nums এবং আরেকটি মান k। আমরা তালিকাটিকে k অ-খালি সাবলিস্টে বিভক্ত করতে পারি। আমাদের k সাবলিস্টের সর্বনিম্ন বৃহত্তম যোগফল খুঁজে বের করতে হবে।
সুতরাং, ইনপুট যদি nums =[2, 4, 3, 5, 12] k =2 এর মত হয়, তাহলে আউটপুট হবে 14, যেমন আমরা তালিকাকে বিভক্ত করতে পারি যেমন:[2, 4, 3, 5] এবং [ 12]।
এটি সমাধান করতে, আমরা এই পদক্ষেপগুলি অনুসরণ করব -
-
একটি ফাংশন সংজ্ঞায়িত করুন ok(), এটি অ্যারে v, k, x,
নেবে -
cnt :=0, যোগফল :=0
-
প্রতিটি উপাদানের জন্য i −
-
যদি যোগফল + i> x হয়, তাহলে −
-
যোগফল :=i
-
(1 দ্বারা cnt বাড়ান)
-
-
অন্যথায়
-
যোগফল :=যোগফল + i
-
-
-
cnt <=k, অন্যথা মিথ্যা
হলে true ফেরত দিন -
প্রধান পদ্ধতি থেকে নিম্নলিখিতগুলি করুন -
-
নিম্ন :=0, ret :=0, উচ্চ :=0
-
প্রতিটি উপাদানের জন্য i সংখ্যায়
-
উচ্চ :=উচ্চ + i
-
ret :=ret + i
-
low :=সর্বাধিক কম এবং i
-
-
যখন কম <=উচ্চ, করুন −
-
মধ্য :=নিম্ন + (উচ্চ - নিম্ন) / 2
-
যদি ok(সংখ্যা, k - 1, mid) সত্য হয়, তাহলে −
-
ret :=মধ্য
-
উচ্চ :=মধ্য - 1
-
-
অন্যথায়
-
নিম্ন :=মধ্য + 1
-
-
-
রিটার্ন রিটার্ন
উদাহরণ
আরো ভালোভাবে বোঝার জন্য আসুন নিচের বাস্তবায়ন দেখি -
#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);
} ইনপুট
{2, 4, 3, 5, 12}, 2 আউটপুট
14