华为机试练习(七)书籍叠放问题

题目描述
假设书本的叠放有这样的规则,当A书的长度和宽度都大于B书时,可以将其B书置于A的上方,堆叠摆放,请设计一个程序,根据输入的书本长宽,计算最多可以堆叠摆放多少本书?

输入
[[16,15], [13, 12], [15, 14]]

输出
3

说明
这里代表有3本书,第1本长宽分别为16和15,第2本长宽为13和12,第3本长宽为15和14,它们可以按照 [13, 12],[15, 14],[16,15] 的顺序堆叠,所以输出3

【分析】
动态规划,实质是求最长递增子序列,但本题有两个因素需要考虑,可以通过排序将长度置为有序,这样其实就是对宽度求最长递增子序列,且可能存在长度相同的情况,在更新dp数组判定时,也要考虑到

【实现】

// 获取输入
const input = "[[16,15], [16, 14], [13, 12], [15, 14]]"
// 转为数组
const arr = JSON.parse(input)
const len = arr.length

// dp数组 dp[i]表示前i本书的最长子序列长度
// 默认为1即每个序列本身就是一个子序列,长度为1
const dp = new Array(len).fill(1)

// 对输入的数组按照长度、宽度的大小进行排序
arr.sort((a, b) => {
    if (a[0] !== b[0]) {
        return a[0] - b[0]
    } else {
        return a[1] - b[1]
    }
})

// 结果,初始为1,即至少可以放一本书
let res = 1

// 从第2本书向前找,看看加上它能不能增加长度
for (let i = 1; i < len; i++) {
	// 要新加的书的长度和宽度
	const cur = arr[i]
    for (let j = 0; j < i; j++) {
    	// 要比较的书的长度和宽度
        const pre = arr[j]
        if (cur[0] > pre[0] && cur[1] > pre[1]) {
        	// 新加的书的长宽均大于当前书,说明这本书可以加在当前书的递增序列之后
        	// 判断此时的递增子序列最大值
            dp[i] = Math.max(dp[i], dp[j] + 1)
        }
        // 更新最大值结果
        res = Math.max(res, dp[i])
    }
}

console.log(res);

你可能感兴趣的:(算法,js,数据结构)