import Control.Monad import Data.List import Text.Printf import qualified Data.Map as M type Pixel = Int type Cost = Int type Diff = Int type Table = M.Map (Maybe Pixel) Cost f :: Cost -> Cost -> Diff -> [Pixel] -> Cost f d i m as = minimum (M.elems tbl) where tbl :: Table tbl = foldl' phi (M.singleton Nothing 0) as phi :: Table -> Pixel -> Table phi tbl p = insert $ M.unionWith min (delete tbl) (modify tbl p) delete :: Table -> Table delete = M.map (+d) modify :: Table -> Pixel -> Table modify tbl p = M.fromAscList $ do y <- [0..255] let c = minimum $ do last <- Nothing : map Just [y-m .. y+m] case M.lookup last tbl of Nothing -> mzero Just c -> return (c + abs (y - p)) return (Just y, c) insert :: Table -> Table insert tbl | m == 0 = tbl | otherwise = M.unionWith min tbl $ M.fromAscList $ do y <- [0..255] let c = minimum [ c + i * ((abs (y-x) + m - 1) `div` m) | (Just x, c) <- M.toList tbl ] return (Just y, c) main :: IO () main = do t <- readLn forM_ [(1::Int)..t] $ \x -> do [d,i,m,n] <- liftM (map read . words) getLine as <- liftM (map read . words) getLine printf "Case #%d: %d\n" x (f d i m as)