ながながとICPC2005 Regional, Tokyo の問題Fを Haskell で.O(n^2) の DP で, 基本的に foldl の2重ネストと.Cで書いた場合と比べて for 文の代わりに foldl になっているだけの違いしかない...
-- Problem F in ACM/ICPC 2005 ASIA Regional Tokyo -- 2005/11/04 O(n^2) DP import Control.Monad import Debug.Trace import List main = getProblems >>= mapM_ (putStrLn.show.solve) getProblems = do [n] <- getNums if n==0 then return [] else do xs <- getNums b <- liftM (head.map read.words) getLine :: IO(Double) [sr,sv,se,sf] <- liftM words getLine liftM ((xs, b, read sr, read sv::Double, read se::Double, read sf::Double):) getProblems where getNums = liftM (map read.words) getLine :: IO([Int]) solve :: ([Int], Double, Int, Double, Double, Double) -> Double solve (ys,b,r,v,e,f) = sl ys [(0.0,0)] where -- xs:rest of checkpoints, cs:best cost for already passed checkpoints sl [] cs = fst $ head cs sl (x:xs) cs = sl xs (best x cs:cs) -- (best cost, current cost, current point) best x cs = (\(bc,c,p) -> (min bc (c + cost (x-p) x),x)) $ foldl op (100000000, 0, x) cs where op (cbc, c, p) (bc, pos) = let c' = c + cost (x-p) (x-pos) in (min cbc (c'+b+bc), c', pos) cost p q = ct p 0.0 where ct p c = if p == q then c else ct (p+1) (c+step p) step p = if p < r then 1.0 / (v-f*fromIntegral(r-p)) else 1.0 / (v-e*fromIntegral(p-r))
- Newer: AWK - はじめ