Problem:
Huge Knapsack Problem

You have N items that you want to put them into a knapsack. Item i has value vi and weight wi.

You want to find a subset of items to put such that:

The total value of the items is as large as possible.

The items have combined weight at most W, that is capacity of the knapsack.

Find the maximum total value of items in the knapsack.

Input

N W
v1 w1
v2 w2
:
vN wN

The first line consists of the integers N and W. In the following N lines, the value and weight of the i-th item are given.

Output

Print the maximum total values of the items in a line.

Constraints

1 ≤ N ≤ 40

1 ≤ vi ≤ 1015

1 ≤ wi ≤ 1015

1 ≤ W ≤ 1015

Sample Input 1

4 5
4 2
5 2
2 1
8 3

Sample Output 1

13

Sample Input 2

2 20
5 9
4 10

Sample Output 2

9

Solution in C (judge verdict: Accepted)

#include<stdio.h>
#include<stdlib.h>
#define NMAX 40
struct node {
  long long int value, weight;
};

int compare(const void *a, const void *b);

int main(void)
{
  int i, j, n, n2, c1 = 0, c2 = 0;
  long long int w, res = 0;
  static struct node vw[NMAX], ps[1<<(NMAX/2)];
  scanf("%d%lld", &n, &w);
  for (i = 0; i < n; i++) scanf("%lld%lld", &vw[i].value, &vw[i].weight);
  n2 = n / 2;
  for (i = 0; i < 1 << n2; i++) {
    long long int sv = 0, sw = 0;
    for (j = 0; j < n2; j++) {
      if (i >> j & 1) {
        sv += vw[j].value;
        sw += vw[j].weight;
      }
    }
    ps[c1].value = sv;
    ps[c1++].weight = sw;
  }
  qsort(ps, c1, sizeof(struct node), compare);
  for (i = 1; i < c1; i++) {
    if (ps[c2].value < ps[i].value) ps[++c2] = ps[i];
  }
  for (i = 0; i < 1 << (n - n2); i++) {
    long long int sv = 0, sw = 0;
    for (j = 0; j < n - n2; j++) {
      if (i >> j & 1) {
        sv += vw[n2+j].value;
        sw += vw[n2+j].weight;
      }
    }
    if (sw <= w) {
      int m, l = 0, r = c2;
      long long int x = w - sw;
      while (l <= r) {
        m = (l + r) / 2;
        if (ps[m].weight > x) r = m - 1;
        else l = m + 1;
      }
      if (sv + ps[r].value > res) res = sv + ps[r].value;
    }
  }
  printf("%lld\n", res);
}

int compare(const void *a, const void *b)
{
  struct node ta = *(struct node*)a, tb = *(struct node*)b;
  if (ta.weight > tb.weight) return 1;
  else if (ta.weight < tb.weight) return -1;
  else if (ta.value > tb.value) return 1;
  else if (ta.value < tb.value) return -1;
  return 0;
}