Есть несколько способов сделать это
Один из подходов - программирование с ограничениями. Это частный случай динамического программирования, предложенного feanor. Целесообразно использовать специализированную библиотеку, которая может выполнять функции ограничения и ветвления за вас. (Google для "gecode" или "comet-online", чтобы найти библиотеки)
Если вы склонны к математике, вы также можете использовать целочисленное программирование для решения этой проблемы. Основная идея здесь состоит в том, чтобы перевести вашу проблему в набор линейных неравенств. (Google для "планирования целочисленного программирования", чтобы найти много примеров из реальной жизни и Google для "Abacus COIN-OR" для полезной библиотеки)
Я предполагаю, что программирование по ограничениям - самый простой подход, но целочисленное программирование полезно, если вы хотите включить в задачу реальные переменные в какой-то момент.