这是对 trincot 的 answer 的一个调整,它不需要创建中间列表,它会计算当前骰子的最小值,从而减少浪费的调用 (.Net Fiddle)。
public static ArrayList combos(int nDice, int tot, int max)
{
var res = new ArrayList();
combos(res, "", nDice, tot, max);
return res;
}
private static void combos(ArrayList res, String sol, int nDice, int tot, int max)
{
if(tot == 0)
{
res.Add(sol);
return;
}
for(int side = 1+(tot-1)/nDice; side <= Math.Min(tot, max); side++)
combos(res, sol+side, nDice-1, tot-side, side);
}
测试:
public static void Main (string[] args) {
int nDice = 3;
int nFaces = 4;
for(int tot=1; tot<=nDice*nFaces+1; tot++)
{
Console.WriteLine ("\nTot: " + tot);
foreach (var combo in combos(nDice, tot, nFaces)) {
Console.WriteLine (combo);
}
}
}
输出:
tot: 1
1
tot: 2
11
2
tot: 3
111
21
3
tot: 4
211
22
31
4
tot: 5
221
311
32
41
tot: 6
222
321
33
411
42
tot: 7
322
331
421
43
tot: 8
332
422
431
44
tot: 9
333
432
441
tot: 10
433
442
tot: 11
443
tot: 12
444
tot: 13