package main import ( "bufio" "fmt" "os" "sort" ) // n<=40 的情况下,可以 meet in the middle func knapsack1(values []int, weights []int, limit int) int { return 0 } // vi 很小的情况下,[dp[i][j]] 表示前 i 个物品,达成总价值为 j 时的最小重量 func knapsack2(values []int, weights []int, limit int) int { return 0 } // wi 很小的情况下,[dp[i][j]] 表示前 i 个物品,取得重量为 j 时的最大价值 func knapsack3(values []int, weights []int, limit int) int { return 0 } // template // struct BranchAndBound { // vector> c; // V best; // BranchAndBound(const vector& v, const vector& w) { // assert(v.size() == w.size()); // vector ord(v.size()); // iota(begin(ord), end(ord), 0); // sort(begin(ord), end(ord), // [&](int i, int j) { return D(v[i]) * w[j] > D(v[j]) * w[i]; }); // for (auto& i : ord) c.emplace_back(v[i], w[i]); // } // pair relax(int i, V v, W w) { // D ret = v; // bool f = true; // while (i < (int)c.size()) { // if (w == 0) break; // if (w >= c[i].second) { // w -= c[i].second, ret += c[i].first, ++i; // continue; // } // f = false, ret += (D(c[i].first) * w) / c[i].second; // break; // } // return make_pair(ret, f); // } // void dfs(int i, V v, W w) { // if (i == (int)c.size()) { // best = max(v, best); // return; // } // auto [rel, flg] = relax(i, v, w); // if (flg) { // best = max(best, V(rel)); // return; // } // if (V(rel) < best) return; // if (w >= c[i].second) dfs(i + 1, v + c[i].first, w - c[i].second); // dfs(i + 1, v, w); // return; // } // V run(W w) { // dfs(0, best = 0, w); // return best; // } // }; // 分枝限定法 n<=2000,vi<=1e9,wi<=1e9,limit<=1e9 // O(2^n) func knapsack4(values []int, weights []int, limit int) int { n := len(values) goods := make([][]int, n) for i := range goods { goods[i] = []int{values[i], weights[i]} } sort.Slice(goods, func(i, j int) bool { return goods[i][0]*goods[j][1] > goods[j][0]*goods[i][1] }) best := 0 relax := func(i, v, w int) (int, bool) { res := v flag := true for i < n { if w == 0 { break } if w >= goods[i][1] { w -= goods[i][1] res += goods[i][0] i++ continue } flag = false res += goods[i][0] * w / goods[i][1] break } return res, flag } var dfs func(i int, v int, w int) dfs = func(i int, v int, w int) { if i == n { if v > best { best = v } return } rel, flag := relax(i, v, w) if flag { if rel > best { best = rel } return } if rel < best { return } if w >= goods[i][1] { dfs(i+1, v+goods[i][0], w-goods[i][1]) } dfs(i+1, v, w) } dfs(0, 0, limit) return best } func main() { in := bufio.NewReader(os.Stdin) out := bufio.NewWriter(os.Stdout) defer out.Flush() var n, limit int fmt.Fscan(in, &n, &limit) values := make([]int, n) weights := make([]int, n) for i := range values { fmt.Fscan(in, &values[i], &weights[i]) } fmt.Fprintln(out, knapsack4(values, weights, limit)) }