То, как сформулирована проблема, говорит о том, что число типов комнат невелико, и поэтому самый большой требуемый размер группы.
Учитывая это, я бы использовал поиск в глубину с памяткой.В Python:
@memoized
def search(n, room_types):
ret = set()
for t in room_types:
if t >= n:
ret.add((t,))
else:
for cfg in search(n - t, room_types):
if sum(cfg) >= n:
ret.add(cfg)
else:
ret.add(tuple(sorted(list(cfg) + [t])))
return ret
print sorted(search(4, (1, 2, 3)))
Это производит:
[(1, 1, 1, 1), (1, 1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]
@memoized
происходит от здесь .