问题
The Golomb's self-describing sequence {G(n)} is the only nondecreasing sequence of natural numbers such that n appears exactly G(n) times in the sequence. The values of G(n) for the first few n are
n 1 2 3 4 5 6 7 8 9 10 11 12
G(n) 1 2 2 3 3 4 4 4 5 5 5 6
Given that G(10^3) = 86, G(10^6) = 6137. Also given that ΣG(n^3) = 153506976 for 1 <= n < 10^3.
Find ΣG(n^3) for 1<= n< 10^6. It is easy to code away the formula for finding the sequence of numbers.But is there any way to track a mathematical relation between G(10^3) and G(10^6) so that the code to find sum upto 10^6 can be optimised ?
回答1:
According to OEIS, we have:
G(1) = 1
G(n+1) = 1 + G(n + 1 - G(G(n)))
If you generate the sequence for a while, you will notice that the size of the groups that repeat k
times is k * G(k)
. For example, what is the size of the groups that repeat 2 times? 2 * G(2) = 4: 2 2 3 3
. Those that repeat 3 times? 3 * G(3) = 6: 4 4 4 5 5 5
(6
repeats 4
times).
Notice that the sum ig(k) = sum i * G(i), i <= k
gives you the size of groups that repeat 1, 2, ..., k
times, So it tells you where the groups that repeat k
times end.
This OEIS formula is also helpful:
for G(1) + G(2)+ ... + G(n-1) < k <= G(1) + G(2) + ... + G(n) = sg(n)
we have G(k) = n
Using this you can get away with computing only a few values of G
to be able to find it for large numbers. For example, let's find G(10^6)
:
First, find k
such that k*G[k] < 10^6 <= (k + 1)*G[k + 1]
. This will help tell you the group G[10^6]
is in, and therefore its value.
Finding this k
will mean that G(10^6)
is in a group of size k + 1
.
I used this C++ program to find this value:
int g[200000], ig[200000];
int main()
{
g[1] = 1;
ig[1] = 1;
for (int i = 2; i < 1000; ++i) {
g[i] = 1 + g[i - g[g[i - 1]]];
ig[i] = ig[i - 1] + i * g[i];
}
int k = 1;
while (ig[k] < 1000000) // 10^6
{
++k;
}
cout << k - 1 << ' ' << ig[k - 1] << endl;
cout << k << ' ' << ig[k] << endl;
return 0;
}
Which gives:
k k * G[k] k + 1 (k + 1) * G[k + 1]
263 998827 264 1008859
Now you need to pinpoint the exact group by using sg
: you find the n
in the OEIS formula by using interpolation between the adjacent ig
values.
This means that:
G(10^6) = sg(k = 263) + (ig(k + 1 = 264) - ig(k = 263)) / (k + 1 = 264)
The exact solution for obtaining the answer and the number of values you need to compute are left as an exercise, ask if you have any problems along the way.
回答2:
Since you're working on https://projecteuler.net/problem=341 I think answering the question directly would be a spoiler. But, if you solve the particular problem there correctly (no matter how non-optimally), the site lets you see an interesting discussion of optimization techniques there.
来源:https://stackoverflow.com/questions/12786087/golombs-sequence