题目地址:http://codeforces.com/contest/777/problem/E
思路:贪心+单调栈。
对于塔的建造,a[j]放在a[i]上面必须是 内环a[i].l<a[j].r<a[i].r 外环,可以先将a[n]按照外环r由大到小排序,当r相同时,由塔建造条件可知应该将 内环l小的放在上面,因此r相同时,l大的排在前面。遍历a[i],将建造塔的a[i]放入单调栈sta中(h大的先出栈),由于r由大到小排序的,栈中的元素t.r都大于a[i].r,则只要比较t.l与a[i].r:
若t.l<a[i].r,表示可以在t加上a[i],则 a[i].h+=t.h,将a[i]入栈(这一过程自动维护了单调栈)
若t.l>=a[i].r,表示a[i]不可放在t上,而后面的a[j].r<a[i].r(j>i) 因此a[j].r<=t.r,故可以将t出栈,继续和栈顶元素比较
每次保存栈顶元素t.h的最大值即为塔的最大高度。
Code :
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
typedef long long LL;
struct node{
int l;
int r;
LL h;
bool operator<(const node &p)const{
return (r==p.r)?l>p.l:r>p.r;
}
};
const int MAX_N=100005;
int n;
node a[MAX_N];
stack<node> sta;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=0;i<n;++i)
cin>>a[i].l>>a[i].r>>a[i].h;
sort(a,a+n);
LL ans=0;
for(int i=0;i<n;++i)
{
LL hi=0;
while(!sta.empty()){
node t=sta.top();
ans=max(ans,t.h);
if(t.l<a[i].r){
hi=t.h; break;
}else sta.pop();
}
a[i].h+=hi;
sta.push(a[i]);
}
ans=max(ans,sta.top().h);
cout<<ans<<endl;
return 0;
}