Problem 150
コンテンツ
http://projecteuler.net/index.php?section=problems&id=150
三角形の高さをnとするとO(n^3)のアルゴリズム。
別のO(n^3)のアルゴリズムも実装したが、そちらより20倍ぐらい速い。
こちらのほうが、領域計算量に関して悪いのだが(rが必要)、なぜか速い。
import Data.List import Data.Array.IArray height = 1000 triangle _ [] = [] triangle n xs = let (y,zs) = splitAt n xs in y:triangle (n+1) zs s = triangle 1.map toS.tail.iterate next $ where next t = (615949*t + 797807) `mod` (2^20) toS t = t - (2^19) -- 三角形配列を横方向に累積和 r = listArray (1,div (height*(height+1)) 2).concatMap (scanl1 (+))$s :: Array Int Integer -- maximum sum of sub triangles -- (x:xs) : 高さhの頂点列 msst m (x:xs) = foldl' minSubTri m xs where minSubTri m y = let m' = minimum.scanl1 (+).take (height+1-h)$ zipWith (-) (right y) (left $ y-1) in min m m' left y | y < x = repeat | otherwise = map (r!).scanl (+) y$[h..] right y = map (r!).scanl (+) y$[h+1..] h = length (x:xs) main = print.foldl' msst .take height.triangle 1$[1..]
十分速いとはいえない。
部分三角形は全部でO(n^3)あるので、O(n^2)のアルゴリズムはないようにも思えるが、
最大部分列和問題はO(n)のアルゴリズムがあるので、
いいアルゴリズムがあるかもしれない。
作成者 Toru Mano
最終更新時刻 2023-01-01 (c70d5a1)