nの倍数が0,1,2で構成される最小の値をf(n)の値をとして、10000までのf(n)/nの値の和を求めようという問題
なかなか計算量が多いのですが、うまくやれば、計算量が減らせそうな感じになってきました。
今のところ、pythonでプログラムを書いてみて、11秒ぐらいかかってます。
(ずいぶん昔のPCではありますが・・)
基本的には、f(n・m)≧f(n)の関係が成り立っているはずです。
・・・f(n・m)がf(n)より小さいとしたら、n・mもnの倍数なので、f(n・m)がf(n)でなければならないのでこうなるはず・・・
それで、過去の値からf(n)を推測できるものがでてきます。
まず、
f(10n)=10f(n)
f(5m)=10f(m) (mは奇数)
です。
g(n)=f(n)/nとすると
g(10n)=g(n)
g(5m)= 2g(m) (mは奇数)
ということになります。
g(n)が偶数であれば、
f(2n)=f(n)で、
g(2n)=g(n)/2 が成立します。
これだけで約4割程度の数字が簡単な計算で求まります。
ただし、f(n・m)=k・f(n)が成り立つかというとそうでもないようです。
さて、f(n)が大きい数字になるのは、nが9で構成されるときなのですが、f(9)を考えてみます。
1桁目で一番大きな数は2なので、2桁目が必要です。
10を9で割った時の余りは1なので、2桁目が2になっても合計は4で3桁目が必要
100を9で割ったあまりは1なので、3桁目が2になったとき合計は6
1000を9で割ったあまりは1なので、4桁目が2になった時合計は8
10000を9で割ったあまりは1で、5桁目が1の時に合計が9になります。
ということでf(9)=12222です。
99の場合も同様に考えることができ、99の場合は100単位で考えます。
そうするとf(99)=1122222222です。
つまり、nの桁数で{0,1,2}で作ることができる数字を1blockとすると5blockが最大です。
しかも9,99,999・・・といった、9のみで構成される数字以外に5blockになるものは存在しないため、
4blockまでの検査で見つかることになります。
nの桁数をdとして、10^d ー n = 1となるもののルールがわかることで、計算量を大きく減らすことができます
それなら10^d ー n = 2,3,4となるものを順に見つけていったら、と考えることもできるのですが、2、5については過去の値から求まりますし、いろんな場合を考えるのもあまり得策ではなさそうです。考えるとしたら11です。しかしルールがわかりません。