Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

โปรแกรมค้นหาผลรวมต่ำสุดของ k รายการย่อยใน C++


สมมติว่าเรามีรายการตัวเลขที่เรียกว่า 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 ใน v -

    • ถ้า sum + i> x แล้ว −

      • ผลรวม :=ผม

      • (เพิ่มขึ้นอีก 1)

    • มิฉะนั้น

      • sum :=sum + i

  • คืนค่า จริง เมื่อ cnt <=k ไม่เช่นนั้น เท็จ

  • จากวิธีหลัก ให้ทำดังต่อไปนี้ −

  • ต่ำ :=0, ถอยหลัง :=0, สูง :=0

  • สำหรับแต่ละองค์ประกอบ i เป็น nums

    • สูง :=สูง + ผม

    • ret :=ret + ผม

    • ต่ำ :=สูงสุดของค่าต่ำสุดและ i

  • ในขณะที่ต่ำ <=สูง ทำ -

    • กลาง :=ต่ำ + (สูง - ต่ำ) / 2

    • ถ้า ok(nums, 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