首页 > 试题广场 >

搭积木

[编程题]搭积木
  • 热度指数:18547 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 50M,其他语言100M
  • 算法知识视频讲解
小明有一袋子长方形的积木,如果一个积木A的长和宽都不大于另外一个积木B的长和宽,则积木A可以搭在积木B的上面。好奇的小明特别想知道这一袋子积木最多可以搭多少层,你能帮他想想办法吗?
定义每一个长方形的长 L 和宽 W ,袋子里面长方形的个数为 n 。
假如袋子里共有5个积木分别为 (2, 2), (2, 4), (3, 3), (2, 5), (4, 5), 则不难判断这些积木最多可以搭成4层, 因为(2, 2) < (2, 4) < (2, 5) < (4, 5)。

数据范围:长方形个数满足

输入描述:
第一行为积木的总个数 N

之后一共有N行,分别对应于每一个积木的宽W和长L


输出描述:
输出总共可以搭的层数
示例1

输入

5
2 2
2 4
3 3
2 5
4 5

输出

4
JS 答案
// O(nlogn), O(n)
let num = readline()
num = parseInt(num)
let arr = []
while(line = readline()) {
    let [w, l] = line.split(' ')
    arr.push([parseInt(w), parseInt(l)])
}


// 1. sort by width increasing order
arr.sort((a,b) => {
    if (a[0] === b[0]) {
        return a[1] - b[1] // must do this also
    } else {
        return a[0] - b[0]
    }
})

// 2. find length of longest increasing subsequence (not continuous)
let nums = arr.map(i => i[1]) // get lengths
const lengthOfLIS = function(nums) {
    if (nums === null || nums.length === 0) return 0;
    if (nums.length === 1) return 1;
    let len = 0; // final ans
    
    let dp = new Array(nums.length).fill(0);
    for (let i = 0; i < nums.length; i++){
        let pos = binarySearchPosition(dp, nums[i], 0, len);
        dp[pos] = nums[i];
        if (pos === len) len++;
    }

    return len;
};

const binarySearchPosition = (dp, target, start, end) => {
    while (start < end) {
        let mid = Math.floor((start + end)/2);
        if (target >= dp[mid]) start = mid+1;
        else end = mid;
    }
    return end;
}

// print
print(lengthOfLIS(nums))

发表于 2020-04-11 15:07:18 回复(0)