我正在解决Baby Blocks问题。我有一些java代码,我想将其转换为Haskell:
爪哇:
for (int i = 1; i <optHeight.length ; i++) {
int maxHeightIndex = 0;
for (int j = i-1; j >=0 ; j--) {
// Need help from here
if(boxes[j].width>boxes[i-1].width && boxes[j].depth>boxes[i-1].depth) {
if(optHeight[maxHeightIndex]<optHeight[j+1]) { <-- How do I write this condition
maxHeightIndex = j+1;
}
}
}
optHeight[i]=optHeight[maxHeightIndex] + boxes[i-1].height;
}
其中optHeight
是一维数组,boxes
是一个由height, width, depth
作为数据成员的对象。在Haskell中,它只是一个列表列表。由于缺少可变阵列/变量,我完全无能为力。
Haskell中:
b list = do
forM_ [1..length list] $ \i -> do
let maxHeight = 0
forM_ [0..(i-1)] $ \j -> do
if list!!j!!1 > list!!i-1!!1 && list!!j!!2 > list !!j!!2 then
maxHeight = j + 1
PS:我完全是Haskell的初学者
答案 0 :(得分:-1)
解决这个问题的方法(我认为)是考虑每个盒子的每次旋转(所以你有3n
个总旋转)。然后,您根据其基数的增加来订购这些。那么问题就是选择“#34; fit&#34;”框中最长的子序列。彼此之间(你不必担心两次挑选相同的盒子,因为盒子永远不适合自己)。这听起来很像规范的longest increasing subsequence问题,这表明我们需要一个动态的编程解决方案。我们将有一个长度为3n
的数组,其中第i个元素表示您可以使用顶部的第i个框创建的堆栈的最大高度。
maxHeight(i) = { height(i) + max[ maxHeight(j) ] such that
width(j) > width(i), depth(j) > depth(i), 0 <= j < i }
现在,让我们开始使用Haskell解决方案。我假设您的输入是维度列表。请注意代码与我描述的解决方案有多接近 - 诀窍是以声明方式编写内容。
import Data.List (sortOn)
import Data.Vector (fromList, (!), generate)
import Data.Ord (Down(..))
babyBlocks :: [(Int,Int,Int)] -> Int
babyBlocks blocks = maxHeights ! (3*n - 1)
where
-- get the number of blocks
n = length blocks
-- generate the `3n` blocks formed by rotating the existing blocks,
-- sort them by their base size, and store them in a vector for
-- fast retrieval
sortedBlocks = fromList
. sortOn (\(x,y,z) -> Down (x*y))
. concatMap (\(x,y,z) -> [(x,y,z),(y,z,x),(z,x,y)])
$ blocks
-- we'll make ourselves a couple helper functions, just so
-- our translation of the recurrence relation looks better
height n = let (_,_,z) = sortedBlocks ! n in z
width n = let (_,y,_) = sortedBlocks ! n in y
depth n = let (x,_,_) = sortedBlocks ! n in x
maxHeight n = maxHeights ! n
-- state the dynamic programming
maxHeights = generate (3*n) (\i ->
height i + maximum (0 : [ maxHeight j | j<-[0..(i-1)]
, width j > width i
, depth j > depth i ]))
你似乎遇到麻烦的部分是最后一部分的动态编程。因为Haskell是懒惰的,所以在定义maxHeight
时使用maxHeights
实际上是完全可以的,即使我不知道我的向量将被初始化为什么顺序!