1from random import randint, seed
23deftotal_to(numbers, target=1000):4"""
5 numbersの中の数字をいくつか組み合わせてtarget以上になる組み合わせのうちベストな組み合わせを返す
6 ベストの基準: targetに近いこと、使用している数字の数が少ないこと、より小さい数字を使用していること
7 該当無しの場合はNoneを返す
8 """9ifsum(numbers)< target:10returnNone11 res =[]12 status ={0:(0,[])}13for n in numbers:14 u =dict()15for k, v in status.items():16if k + n >= target:17 res.append((k+n,len(v[1])+1,sorted(v[1]+[n])))18elif k+n notin status or status[k+n]>(v[0]+1, v[1]+[n]):19 u[k+n]=(v[0]+1,sorted(v[1]+[n]))20 status.update(u)21returnsorted(res)[0][2]222324#numbers = [211, 543, 1200, 365, 911, 89, 21, 460, 799]25seed(3)# 乱数の固定用26numbers =[randint(10,1100)for _ inrange(100)]# 10~1100の乱数を100個生成27print(numbers)2829whileTrue:30 picks = total_to(numbers)31if picks:32print(f'{picks}, ({sum(picks)})')33for p in picks:34 numbers.remove(p)35else:36print(f'残り:{numbers}')37break