HDU 3458 Rectangles Too!

来源:互联网 发布:淘宝一折特卖 - 百度 编辑:程序博客网 时间:2024/04/30 21:16

看到一个神奇做法的代码~

 

代码来自:http://hi.baidu.com/%B1%BF%D0%A1%BA%A2_shw/blog/item/ad73c309a21dbd3de92488f5.html

 

 

这个解法的另一讲解:

 

今天搞会了另一种犀利的解法。。。 不用二分也能够 跑的很快。。比我的写的线段树快多了。神奇的解法啊。。
在此感谢 hh 大牛的代码。 
首先把每个矩形都拆成两部分。 右上角的点和左下角的点。。记录原来的下标。
然后按照x 来做一次排序。。如果 x 相等 则 左边的点优先。(因为这样可以避免 x 相等时 , y 小的更新点先于查询点。而导致错误)。
开一个队列来保存 dp[ x ] 的最小 y; (因为 x 是非递减排序。。所以每次只要找 y 即可。把限制条件转化为一个。这时候就可以用上二分了。 而 队列 保存的 某个最长序列 的 y 的最小值,这样可以保证结果不被漏掉。可用反证法证明)。
从小到大线性扫描一遍。。
如果 是 左边的点。 则查询这个点 y 在队列里的位置。。即可得出 该点的最有解。。。
如果是 右边的点。 (因为题目保证 右边的点大于左边的点。所以他的解已经求出)用其最有解来更新队列。
最后队列里保存着一组 y 小标最小的 最优解。
答案显然。
该方法通过 巧妙的拆点和 用队列保存最优解的 y 最小。 把 该问题转化成LIS 问题。。。时间复杂度为 O(n × log n);

 

来自:http://yxq0620.blog.163.com/blog/static/44494392201061894618375/

 

我很纳闷我写的代码也是基于nlogn求最长上升子序列的思想(排序后建一个栈,对于每个元素:1.如果栈空,入栈,否则 2.如果大于栈顶元素,入栈,否则 3.二分查找一对相邻元素,若前面元素小于他、后面元素大于等于他,然后插入到相邻元素中间。),总是过不去。是因为没有拆开?还是是重载运算符的函数写得不好?我再琢磨琢磨。。

原创粉丝点击