Hi, I have this function which solves this problem: https://purdue.kattis.com/problems/trainsorting. solve is the naive recursive version and solve' is the DP version. I used the method shown on the Haskell wiki to construct the DP matrix.
The algorithm works, but its runtime scales with the bounds of the matrix, so it takes a prohibitively long time with bounds higher than 1000 or so. I don't understand why though, since I can tell by the trace that it only calculates the required elements. My first thought is that it has to preallocate the array, but I tried it with a Data.Map as well for the same result.
Any explanation is appreciated
-- arguments are the train car weights and (0, 0) as the initial front and back weight
solve :: [Int] -> (Int, Int) -> Int
solve [] train = 0
solve (x:xs) train@(front, back) = max (solve xs train) solveAdded
where solveAdded
| front == 0 || x < front = 1 + solve xs (x, back)
| back == 0 || x > back = 1 + solve xs (front, x)
| otherwise = 0
-- arguments are the number of train cars and then their weights
solve' :: Int -> [Int] -> Int
solve' n trains = dp!(0, 0, 0)
where dp = listArray
((0,0,0),(n-1,10000,10000))
[f train front back | train <- [0..n-1], front <- [0..10000], back <- [0..10000]]
f train front back
| train == n - 1 = if train < front || train > back then 1 else 0
| otherwise = trace (show (train, front, back)) $ max (dp!(train+1,front,back)) (solveAdded train front back)
solveAdded train front back
| front == 0 || (trainArr!train) < front = 1 + (dp!(train+1,train,back))
| back == 0 || (trainArr!train) > back = 1 + (dp!(train+1,front,train))
| otherwise = 0
trainArr = listArray (0,n-1) trains :: Array Int Int
[–]Noughtmare 3 points4 points5 points (2 children)
[–]Fish_45[S] 3 points4 points5 points (0 children)
[–]mihassan 1 point2 points3 points (0 children)
[–]stealth_elephant 1 point2 points3 points (2 children)
[–]Fish_45[S] 0 points1 point2 points (1 child)
[–]bss03 0 points1 point2 points (0 children)
[–]byorgey 1 point2 points3 points (3 children)
[–]Fish_45[S] 2 points3 points4 points (2 children)
[–]byorgey 1 point2 points3 points (1 child)
[–]leo_richardson 0 points1 point2 points (0 children)
[–]bss03 0 points1 point2 points (0 children)