Problem 78
コンテンツ
http://projecteuler.net/index.php?section=problems&id=78
今までと同じ方法はかなり時間がかかる。
まぁ、そこで、google先生ですよ。
結果できたのが下。
import Data.List import Data.Array.IArray import Data.Maybe import Control.Monad ini = array (,) [(,1)]::Array Integer Integer piles l a m = ps where ps = listArray (,m) $ elems a++[p n `mod` l | n<-[m'+1..m]] ::Array Integer Integer (,m') = bounds a p n = sum [(s*).(ps!)$n-k|(s,k) <- takeWhile((<=n).snd) penta] penta = zip (cycle [1,1,-1,-1]). concat.zipWith( a b -> [a,b])(scanl1(+)[1,4..]) $ scanl1(+)[2,5..] main = print.fst.fromJust.msum. map (find((==).snd).assocs).scanl (piles$10^6) ini.iterate (2*) $100
DP。
先と同様に所与の探索範囲で見つからなかったら、探索範囲を2倍にしてもう一度DPを行うが
この際、前の計算結果を利用しているのが高速化の工夫その1。
(これで倍速ぐらいになると思われる。前は面倒だからやっていなかった。)
その2はmodをとっていること。多倍長の計算は時間がかかる。
必要なのは10^6で割ったあまりだけ。
実際これも倍速ぐらいになった。
作成者 Toru Mano
最終更新時刻 2023-01-01 (c70d5a1)