Nice solution. I think you can still improve a bit. Whenever you get List<Integer> reduceNeeds before checking if(reduceNeeds!=null) and calling recursion if it is not null,you can check one more time in your map like map.containsKey(reduceNeeds.toString()) and if its null you can call your recursion.
Is it possible to ignore time limits or to further raise them? I would be ok with my solution not being considered "accepted", but I'd like to know if my outputs are correct.
Immutable / functional code is sometimes an order of magnitude slower than its mutable counterpart (estimation I've heard thrown around), but it's the style of programming that is used for my line of work. Scala compile times are also known to be pretty poor unfortunately.
I noticed the way you generate the hashcode. Pretty smart, since there are only 6 in max you need to buy for each item. But when the problem goes bigger, let's say more than 10. This "hash code" is not unique. Just a reminder. :)