То, что вы пытаетесь перечислить, называется k -милликомбинацией. Проблема часто формулируется так: учитывая n неразличимых шаров и k ящиков, перечислите все возможные способы распределения всех шаров в ящиках. Количество таких распределений:
factorial(n + k - 1) / (factorial(k - 1) * factorial(n))
Дополнительную информацию см. В методе 4 из Двенадцатикратного пути .
Вот код для перечисления распределений (C ++):
string & ListMultisets(unsigned au4Boxes, unsigned au4Balls, string & strOut = string ( ), string strBuild = string ( ))
{
unsigned au4;
if (au4Boxes > 1) for (au4 = 0; au4 <= au4Balls; au4++)
{
stringstream ss;
ss << strBuild << (strBuild.size() == 0 ? "" : ",") << au4Balls - au4;
ListMultisets (au4Boxes - 1, au4, strOut, ss.str ( ));
}
else
{
stringstream ss;
ss << "(" << strBuild << (strBuild.size() == 0 ? "" : ",") << au4Balls << ")\n";
strOut += ss.str ( );
}
return strOut;
}
int main(int argc, char * [])
{
cout << endl << ListMultisets (3, 5) << endl;
return 0;
}
Вот вывод из вышеприведенной программы (5 шаров, распределенных по трем коробкам):
(5,0,0)
(4,1,0)
(4,0,1)
(3,2,0)
(3,1,1)
(3,0,2)
(2,3,0)
(2,2,1)
(2,1,2)
(2,0,3)
(1,4,0)
(1,3,1)
(1,2,2)
(1,1,3)
(1,0,4)
(0,5,0)
(0,4,1)
(0,3,2)
(0,2,3)
(0,1,4)
(0,0,5)