题目传送门:UVA 437 巴比伦塔
题意:有n(n≤30)种立方体,每种都有无穷多个。要求选一些立方体摞成一根尽量高的柱子(可以自行选择哪一条边作为高),使得每个立方体的底面长宽分别严格小于它下方立方体的底面长宽。
分析:这个一看就是DAG上的最长路,瞬间写出状态转移方程:
以dp[i][j]表示当前立方体长款分别为i和j,往它上面堆立方体,使其满足条件的最大高度
则dp[i][j] = max(dp[x][y]+h),x,y,h是某个立方体的长宽高并且满足x<i,y<j
这样写起来很简单啊,问题是题目并没说长宽范围,二维的dp数组不知道该开多大。。。
既然是二维的,那数字应该不是很大,就设置为1000好了,然后:
额,尴尬,好吧,设置成10000吧,数据再大就没法做了啊,于是~~
嗯,一下子AC不了了啊~
回头再看一下算法思路,dp[i][j]两个索引,一个表示长,一个表示宽,它俩都是一个立方体里的,换句话说,i和j存在的意思是为了确定当前是哪个立方体在下面,并且要确定底面——立方体可以直接用立方体的序号来表示,这一维只有30的大小。然后就是确定底面了,换句话说,确定立方体的哪条边作为高~立方体有三条边,可以用一个数组表示,也就是每条边也对应着一个序号——这就出来了,可以像用序号确定立方体一样,用序号来确定高,也就是确定底边——嗯,dp数组的第二维出来了