Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

C++에서 k 하위 목록의 최소 최대 합을 찾는 프로그램

<시간/>

nums라는 숫자 목록과 다른 값 k가 있다고 가정합니다. 목록을 k개의 비어 있지 않은 하위 목록으로 분할할 수 있습니다. k 하위 목록의 최소 최대 합을 찾아야 합니다.

따라서 입력이 nums =[2, 4, 3, 5, 12] k =2와 같으면 [2, 4, 3, 5] 및 [ 12].

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • ok() 함수를 정의하면 배열 v, k, x,

    가 사용됩니다.
  • cnt :=0, 합계 :=0

  • v −

    의 각 요소 i에 대해
    • 합계 + i> x이면 -

      • 합계 :=나는

      • (cnt를 1씩 증가)

    • 그렇지 않으면

      • 합계 :=합계 + i

  • cnt <=k이면 true를 반환하고, 그렇지 않으면 false

    를 반환합니다.
  • 주요 방법에서 다음을 수행하십시오 -

  • 낮음 :=0, ret :=0, 높음 :=0

  • 숫자의 각 요소 i에 대해

    • 높음 :=높음 + i

    • 렛 :=렛 + i

    • 낮음 :=낮음 및 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