如果有人能指出我正确的方向,我真的很感激。我试图找到各种数字的所有不同组合,每个组合具有不同数量的列(在C ++中)。例如,考虑数字2:
两栏:
2 = {2,0} {0,2} {1,1}
三栏:
2 = {0,0,2} {0,2,0} {2,0,0} {1,1,0} {0,1,1} {1,0,1}}
四列:
2 = {0,0,0,2} {0,0,2,0} {0,2,0,0} {2,0,0,0} {1,1,0,0} {0,0,1,1} {0,1,1,0} {1,0,0,1} {1,0,1,0} {0,1,0,1}
提前感谢!
答案 0 :(得分:1)
这是我的尝试:
void combinations(int n, int columns, std::vector<int>& soFar)
{
if (columns == 1)
{
for (auto e : soFar)
std::cout << e << " ";
std::cout << n << '\n';
return;
}
for (int i = 0; i <= n; ++i)
{
soFar.push_back(i);
combinations(n - i, columns - 1, soFar);
soFar.pop_back();
}
}
void combinations(int n, int columns)
{
std::vector<int> soFar;
combinations(n, columns, soFar);
}
基本上,您将数字分成两个子部分,直到达到深度限制(您的情况下的列数)。
为了在备份的路上继续打印以前的数字,我将它们存储在soFar
向量中,相应地推送和弹出它们。
以下是combinations(2, 4)
的输出:
0 0 0 2
0 0 1 1
0 0 2 0
0 1 0 1
0 1 1 0
0 2 0 0
1 0 0 1
1 0 1 0
1 1 0 0
2 0 0 0
答案 1 :(得分:0)
考虑将问题分成两个子问题:
1)查找添加到您的号码的所有数字组合:
即:“3”的2列情况:(2,1)和(3,0)
2)置换您找到的所有组合:
即:(2,1) - &gt; (2,1),(1,2)和(3,0) - > (3,0),(0,3)
对于第1部分),你会遇到大数字和许多列的问题,比如5列4列(我知道,它们是不可思议的巨大数字):
5 = 4 + 1
5 = 3 + 2
5 = 3 + 1 + 1
5 = 2 + 1 + 1 + 1
5 = 1 + 1 + 1 + 1 + 1
如果你仔细观察,你有可能递归。如同,对于5 = 3 + 2:找到3的组合和2的组合等等......直到你到达1
一旦你说递归,树结构开始听起来很有趣。这就是我解决问题的方法。
答案 2 :(得分:0)
这是一个直接的组合学问题。如果你有m列,那么你在列之间有m-1个分隔符。使用数字n,您需要所有方式来订购m-1个分隔符和n个元素。例如,当n = 5且m = 3时,一种可能的排列是xx,x,xx - 你看7选择2。
所以一般的解决方案是m + n-1选择m-1,或者等价地,m + n-1选择n。
x选择y的公式是x! / [y! *(x-y)!]