배열과 합계 값이 제공됩니다. 문제는 주어진 합계 값을 초과하지 않는 최대 부분 집합 합계를 계산하는 것입니다. 주어진 배열의 구조가 분할 정복 방식과 동일하지 않기 때문에 여기에 무차별 대입 방식을 적용할 수 없습니다.
이에 대한 다양한 입력 출력 시나리오를 살펴보겠습니다. -
예를 들어 이해하자
입력 − long arr[] ={ 21, 1, 2, 45, 9, 8 } long given_Sum =12
출력 - 주어진 합보다 작거나 같은 합을 갖는 최대 합 부분집합-->12
설명 − 배열은 2개의 부분 집합으로 분할됩니다. 첫 번째 요소에는 n/2개의 요소가 있고 나중에는 나머지 요소가 있습니다. 첫 번째 부분 집합의 모든 가능한 부분 집합 합이 계산되어 배열 A에 저장되고 유사하게 나중 부분 집합의 부분 집합 합이 계산되어 배열 B에 저장됩니다. 마지막으로 두 하위 문제는 합이 더 작거나 같도록 병합됩니다. 주어진 합계에.
입력 − long arr[] ={ 2, 12, 16, 25, 17, 27 } long given_Sum =24;
출력 - 주어진 합보다 작거나 같은 합을 갖는 최대 합 부분집합-->19
설명 − 배열은 2개의 부분 집합으로 분할됩니다. 첫 번째 요소에는 n/2개의 요소가 있고 나중에는 나머지 요소가 있습니다. 첫 번째 부분 집합의 모든 가능한 부분 집합 합이 계산되어 배열 A에 저장되고 유사하게 나중 부분 집합의 부분 집합 합이 계산되어 배열 B에 저장됩니다. 마지막으로 두 하위 문제는 합이 더 작거나 같도록 병합됩니다. 주어진 합계에.
아래 프로그램에서 사용된 접근 방식은 다음과 같습니다 -
-
데이터 유형이 긴 배열과 데이터 유형이 긴 변수를 생성하고 10으로 설정합니다. 함수를 countSubsetSum(arr, arr.length, given_Sum))으로 호출합니다.
-
메소드 내부에서,calculateSubsetSum(arr, arr.length, given_Sum))
-
이 메서드를 solve_subarray(a, A, len / 2, 0) 및 solve_subarray(a, B, len - len / 2, len / 2)
로 호출합니다. -
A와 B의 크기를 계산한 다음 sort() 메서드를 사용하여 배열 B를 정렬합니다.
-
i에서 0까지 FOR 루프를 시작하여 배열 A의 크기보다 작습니다. IF A[i]가 given_Sum보다 작은지 확인한 다음 get_lower_bound를calculate_lower_bound(B, given_Sum - A[i])로 설정합니다. 확인, get_lower_boundto size_B 또는 B[get_lower_bound]가 (given_Sum - A[i]))와 같지 않은 경우 get_lower_bound를 1만큼 감소시킵니다.
-
IF B[get_lower_bound] + A[i])가 max보다 큰지 확인한 다음 max를 B[get_lower_bound] + A[i]로 설정합니다.
-
최대 반환
-
-
메서드 내부에서 solve_subarray(long a[], long x[], int n, int c)
-
i가 (1 <
-
j가 n보다 작을 때까지 루프 FOR를 j에서 0으로 시작합니다. 루프 내에서 IF i &(1 <
-
x[i]를 합계로 설정
-
-
메소드 내부에서, compute_lower_bound(long a[], long x)
-
배열 1의 왼쪽은 -1, 오른쪽은 길이로 변수를 선언합니다.
-
루프 시작 WHILE 왼쪽 + 오른쪽보다 1 작습니다. while 내부에서 m을 (left + right)>>> 1로 설정합니다. IF a[m]이 x보다 큰지 확인하고 right를 m으로 설정합니다.
-
그렇지 않으면 왼쪽을 m으로 설정합니다.
-
오른쪽으로 돌아가세요.
-
예시
import java.util.*;
import java.lang.*;
import java.io.*;
public class testClass{
static long A[] = new long[2000005];
static long B[] = new long[2000005];
static void solve_subarray(long a[], long x[], int n, int c){
for (int i = 0; i < (1 << n); i++){
long sum = 0;
for (int j = 0; j < n; j++){
if ((i & (1 << j)) == 0){
sum += a[j + c];
}
}
x[i] = sum;
}
}
static long calculateSubsetSum(long a[], int len, long given_Sum){
solve_subarray(a, A, len / 2, 0);
solve_subarray(a, B, len - len / 2, len / 2);
int size_A = 1 << (len / 2);
int size_B = 1 << (len - len / 2);
Arrays.sort(B);
long max = 0;
for (int i = 0; i < size_A; i++){
if (A[i] <= given_Sum){
int get_lower_bound = calculate_lower_bound(B, given_Sum - A[i]);
if (get_lower_bound == size_B || B[get_lower_bound] != (given_Sum - A[i])){
get_lower_bound--;
}
if((B[get_lower_bound] + A[i]) > max){
max = B[get_lower_bound] + A[i];
}
}
}
return max;
}
static int calculate_lower_bound(long a[], long x){
int left = -1, right = a.length;
while (left + 1 < right){
int m = (left + right) >>> 1;
if (a[m] >= x){
right = m;
}
else{
left = m;
}
}
return right;
}
public static void main(String[] args){
long arr[] = { 21, 1, 2, 45, 9, 8 };
long given_Sum = 12;
System.out.println("The maximum sum subset having sum less than or equal to the given sum-->" + calculateSubsetSum(arr, arr.length, given_Sum));
}
} 출력
위의 코드를 실행하면 다음과 같은 출력이 생성됩니다.
The maximum sum subset having sum less than or equal to the given sum-->12