import java.util.*; public class MeetInTheMiddle { public static long sumsLowerBound(long[] a, long b) { int n = a.length; int sizeL = 1 << (n / 2); int sizeR = 1 << (n - n / 2); long[] sumsL = new long[sizeL]; long[] sumsR = new long[sizeR]; for (int i = 0; i < sizeL; ++i) for (int j = 0; j < n / 2; ++j) if ((i & (1 << j)) > 0) sumsL[i] += a[j]; for (int i = 0; i < sizeR; ++i) for (int j = 0; j < n - n / 2; ++j) if ((i & (1 << j)) > 0) sumsR[i] += a[j + n / 2]; Arrays.sort(sumsL); Arrays.sort(sumsR); int left = 0; int right = sizeR - 1; long cur = Long.MIN_VALUE; while (left < sizeL && right >= 0) { if (sumsL[left] + sumsR[right] <= b) { cur = Math.max(cur, sumsL[left] + sumsR[right]); ++left; } else { --right; } } return cur; } // Usage example public static void main(String[] args) { long[] a = { 1, 2, 5 }; System.out.println(3 == sumsLowerBound(a, 4)); } }