#include #include #include #include #include using namespace std; typedef long long int ll; typedef pair pll; const ll INF = 1LL << 60; const int SIZE = 5010; ll N, W; ll best_feasible = -INF; // value, weight pll elem[SIZE]; ll v[SIZE], w[SIZE]; // 線形緩和問題 (離散的ではなく、連続なものを扱う) // idx 未満まではどう選んだかが確定していて、idx 以降は未確定 pair Relaxation(int idx, const bitset &b) { double ans = 0; double cur_w = W; for(int j=0; j(cur_w, w[j]); ret &= (tmp == 0 || tmp == w[j]); cur_w -= tmp; ans += tmp * (v[j] * 1.0 / w[j]); } return make_pair(ans, ret); } ll dfs(int idx, bitset &b, ll cur_v, ll cur_w) { if(idx == N) { best_feasible = max(best_feasible, cur_v); return cur_v; } auto relax_p = Relaxation(idx, b); double relax = relax_p.first; bool satis = relax_p.second; // 元の制約を満たしているなら、それが最適になるかも if(satis) { best_feasible = max(best_feasible, relax); return relax; } // 緩和して貪欲に取ったのに許容解より低い → どうやっても更新できないので抜けよう if(relax < best_feasible) { return -INF; } ll tmp = -INF; // i 番目を取る if(cur_w + w[idx] <= W) { b[idx] = 1; tmp = max(tmp, dfs(idx+1, b, cur_v + v[idx], cur_w + w[idx])); b[idx] = 0; best_feasible = max(best_feasible, tmp); } // i 番目を取らない tmp = max(tmp, dfs(idx+1, b, cur_v, cur_w)); best_feasible = max(best_feasible, tmp); return tmp; } int main() { scanf("%lld%lld", &N, &W); for(int i=0; i a.second * b.first; }); for(int i=0; i b; dfs(0, b, 0, 0); printf("%lld\n", best_feasible); return 0; }