https://paiza.jp/poh/ec-campaign/
あなたとJava
- まずはScannerでいいや
- 入力、普通にソートした方がいいよね
- 例えば
[19, 27, 35, 43, 51, 68, 76, 84, 92, 100]
みたいに商品があって、目標金額が80のとき、探索範囲は
[19, 27, 35, 43, 51, 68, 76]
でいいので、それ以降は探索範囲に入れないようにする - ある目標価格、仮に80に対して、左側から19に最適の商品、27に最適の商品...と探していくとき、
27に対応する51、51に対する27は同じ組だから、対応する商品は選んだ1個目の商品の右側から探せば無駄無し。
51に対応する商品を探すときは[68, 76] // 27との組み合わせは発見済み
でよい。 - 相対的に右側の商品が安くなることは無いので、
目標価格80について、27に対する最適の組み合わせ商品は、19に対する最適の組み合わせ商品より右側にはない。よって
[19, 27, 35, 43, 51, 68, 76]
の19に対応する最適の組み合わせである68を
[27, 35, 43, 51, 68, 76]
から探したら、27に対する最適の組み合わせは
[35, 43, 51, 68] // 27より右側だが、さっきみつけた68より右にはない!
- これを繰り返して、探索範囲がなくなってしまったり、探索範囲の中に合計が目標価格を下回る組み合わせ候補がなかったら、既に見つかった組み合わせ価格の合計の最高値が答えである。
- 組み合わせの探索は二分探索でやろう。
みたいなことを考えて、適当に書いた。タイムは[0.13, 0.23, 1.40]
BufferedReader最高。あと出力も一回にまとめる。 タイムは[0.8, 0.12, 0.76]
目標金額ぴったりで探索打ち切るようにした。タイムは[0.8, 0.9, 0.18]
最大金額が1Mなので、メモリをいっぱい使ってバケットソートした。
このとき、同じ価格の商品が2個以上連続しないようにした。
タイムは[0.9, 0.9, 0.15] ケース1ではサイズ小さすぎて逆効果
二分探索を明らかに目標金額より大きい商品を探索範囲から抜くときだけにし、
探索範囲をシーケンシャルに走査することにした(必要以上の重複は取り除いたのだから)
タイム変わらずもうだめぽ。
隣の席で同僚が言語最速出してた
自己ベスト : http://paiza.jp/poh/ec-campaign/result/f5b702f1e4b2644e7e9a3d0b3d8e36ad