Golomb's sequence

不问归期 提交于 2019-12-04 14:42:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!