Note
In the first sample, the optimal solution is to take all the rings and put them on each other in order 3, 2, 1.
In the second sample, one can put the ring 3 on the ring 4 and get the tower of height 3, or put the ring 1 on the ring 2 and get the tower of height 4.
题目给出了一堆指环的内径a、外径b、高h,要把指环叠成塔,
即外径从下往上不递增,同时两个上下相邻的指环中上面的指环
的外径要大于下面指环的内径(不然上面的指环就掉下去了),
求最高的塔。
求塔,即求一个从下往上不递增的序列,那么就可能可以借鉴最长上升子序列(LIS)
的思路了,即设dp[i]为以指环i为终点(这里的终点可以指塔顶)所能得到的
最高的塔的高度,然后状态方程为
dp[i] = max(dp[j]) + h(i) ,( 1<=j<=n, b(j) >= b(i) ,a(j) < b(i) )
将指环以b(i)从大到小的顺序排序优化下,可得
dp[i] = max(dp[j]) + h(i), ( 1<=j 这样的时间复杂度为O(n^2),还是过大,那么可以考虑用数据结构去维护
max(dp[j])(1<=j 的dp[i],使得下一轮找a(j) 因为每轮查询都要查询a(j) 考虑先将所有a(i)提取出来并排序离散化为单调数组,然后每次查询就可用
b(i)去二分查询单调数组,得到单调离散数组的一个下标。
也就是拿单调离散数组的下标去映射a[i]。
然后就只需要用树状数组/线段树去维护区间最大值了。
------------------
一开始用线段树不小心写成了区间更新,还加上了lazy操作,wa了几次。。
改成单点更新就过了。。
//树状数组
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//线段树,多了无意义的lazy操作。。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include