|
>アプローチとしては,他にN桁で連続する最大数がMbitの数をいきなり算出してしまう,
>という方法もあります。
>ただ,そちらは作るのが面倒そうです。
そのアプローチで(自称)超高速なものが出来ました。(今度は確認済みです)
確かに作る前から、既に面倒でした。
#include <stdio.h>
#define N 20
unsigned long cnt[N+1];
unsigned long sig(int m, int n)
{
unsigned long s = 0;
if (m <= 1) return n;
for (m--; n > 0; n--)
s += sig(m, n);
return s;
}
unsigned long comb(int m)
{
unsigned long i, j;
double f = 1;
for (i = 0; i <= N; i++)
if (cnt[1] == m) return 1;
while (m > 1) f *= m--;
for (i = 0; i <= N; i++)
for (j = cnt[i]; j > 1; j--)
f /= j;
return (unsigned long)f;
}
unsigned long sum(int m, int n, int d)
{
unsigned long s = 0;
for (; d > 0; d--)
if (n >= d) {
cnt[d]++;
s += sig(m + 1, n - d + 1) * comb(m + 1);
s += sum(m + 1, n - d - 1, d);
cnt[d]--;
}
return s;
}
int main(void)
{
int i;
printf(" 0: 1\n");
for (i = 1; i <= N; i++) {
cnt[i]++;
printf("%2d: %lu\n", i, N-i+1 + sum(1, N - i - 1, i));
cnt[i]--;
}
return 0;
}
|