, ! , , , . , , , .
" 18 ", " 1 10 ^ 18". ( 18 18- .)
, , , .
dig 1 9, 0, . ( 18 - sum(dig). :
recurse(dig[], pos) {
if (digitsum(dig) > 60) return;
if (digitsum(dig) == 60) {
count += poss(dig)
} else {
if (pos < 9) recurse(dig, pos + 1);
if (sum(dig) < 18) {
dig[pos]++;
recurse(dig, pos);
dig[pos]--;
}
}
}
, 60. 60 , , :
poss(dig) = 18! / prod(dig[i]!)
prod(dig[i]!) . (, , 0! == 1.)
, . , 60 50 5 000 000 000, .
, , A B. 0 10 ^ n, n- , .
- , . , 5x 9 3x 5, 60. , 18 . 590,050,005,090,900,099 - , . 18 - (5 + 3) = 10 ,
N(5x9, 3x5) = 18! / (5! * 3! * 10!)
.
. , dig:
^ count
|
2x ... ... ... ... ... ... ... ... ...
1x ... ... ... ... ... ... ... ... ...
0x ... ... ... ... ... ... ... ... ...
---------------------------------------------> pos
1 2 3 4 5 6 7 8 9
dig == [0, 0, 0, 0, 3, 0, 0, 0, 5]
, . pos. , , . , S, pos 9. , S, , .
, : .
18- , 60 .
, . , 18! 64- , 20! . (, N! / prod(dig[i]!).)
. , . bare-bones:
ds_count(i, sum)
{
if (sum > 60) return 0;
if (i == 18) {
if (sum == 60) return 1;
return 0;
}
result = 0;
for (d = 0; d < 10; d++) {
result += ds_count(i + 1, sum + d);
}
return result;
}
18- . , 60, . , .
. , , . , ds_count(2, 5) 05..., 14..., 23..., 32..., 41... 50.... ( Settlers of Catan, .)
, 5 16 . :
ds_count(i, sum)
{
if (sum > 60) return 0;
if (i == 18) {
if (sum == 60) return 1;
return 0;
}
if (defined(memo[i, sum])) return memo[i, sum];
result = 0;
for (d = 0; d < 10; d++) {
result += ds_count(i + 1, sum + d);
}
memo[i, sum] = result;
return result;
}
, . , .
, memoizing. ( memoizing , .) zig-zag - . , , memoising .