44from functools import reduce , lru_cache
55from heapq import heappush , heappop , heapify
66
7- import itertools
7+ from itertools import *
88import math , fractions
99import sys , copy
1010
@@ -24,6 +24,9 @@ def LSR(n): return [LS() for _ in range(n)]
2424
2525def perm (n , r ): return math .factorial (n ) // math .factorial (r )
2626def comb (n , r ): return math .factorial (n ) // (math .factorial (r ) * math .factorial (n - r ))
27+ def powerset (iterable ):
28+ s = list (iterable )
29+ return chain .from_iterable (combinations (s , r ) for r in range (len (s )+ 1 ))
2730
2831def make_list (n , * args , default = 0 ): return [make_list (* args , default = default ) for _ in range (n )] if args else [default for _ in range (n )]
2932
@@ -37,7 +40,70 @@ def make_list(n, *args, default=0): return [make_list(*args, default=default) fo
3740sys .setrecursionlimit (1000000 )
3841
3942def main ():
40- N = I ()
43+ N , W = LI ()
44+ vw = LIR (N )
45+ maxw = max (w for v , w in vw )
46+ maxv = max (v for v , w in vw )
47+
48+ if N <= 30 :
49+ ans = 0
50+
51+ first = vw [:N // 2 + 1 ]
52+ d = defaultdict (int )
53+ for s in powerset (first ):
54+ sv , sw = 0 , 0
55+ for v , w in s :
56+ sv += v
57+ sw += w
58+ d [sw ] = max (d [sw ], sv )
59+ cand = sorted ([(v , w ) for w , v in d .items ()], key = lambda x : x [1 ])
60+ l = [cand [0 ]]
61+
62+ for v , w in cand :
63+ if v > l [- 1 ][0 ]: l .append ((v , w ))
64+
65+ second = vw [N // 2 + 1 :]
66+ for s in powerset (second ):
67+ sv , sw = 0 , 0
68+ for v , w in s :
69+ sw += w
70+ sv += v
71+ rest = W - sw
72+ if rest < 0 : continue
73+
74+ left , right = - 1 , len (l )
75+ while right - left > 1 :
76+ mid = (left + right ) // 2
77+ if l [mid ][1 ] > rest : right = mid
78+ else : left = mid
79+ ans = max (ans , sv + l [left ][0 ])
80+ print (ans )
81+
82+
83+ elif maxw <= 1000 :
84+ dp = make_list (N + 1 , N * maxw + 1 )
85+ for i in range (N ):
86+ v , w = vw [i ]
87+ for j in range (N * maxw + 1 ):
88+ if j - w >= 0 :
89+ dp [i + 1 ][j ] = max (dp [i ][j ], dp [i ][j - w ] + v )
90+ else :
91+ dp [i + 1 ][j ] = dp [i ][j ]
92+
93+ print (dp [N ][min (W , N * maxw )])
94+
95+
96+ elif maxv <= 1000 :
97+ dp = make_list (N + 1 , N * maxv + 1 , default = N * maxw + 1 )
98+ dp [0 ][0 ] = 0
99+ for i in range (N ):
100+ v , w = vw [i ]
101+ for j in range (N * maxv + 1 ):
102+ if j - v >= 0 :
103+ dp [i + 1 ][j ] = min (dp [i ][j ], dp [i ][j - v ] + w )
104+ else :
105+ dp [i + 1 ][j ] = dp [i ][j ]
106+ print (max ([v for v , w in enumerate (dp [N ]) if w <= W ]))
41107
42108if __name__ == '__main__' :
43109 main ()
0 commit comments