题目原文:http://codeforces.com/contest/777/problem/E
Of course you have heard the famous task about Hanoi Towers, but did you know that there is a special factory producing the rings for this wonderful game? Once upon a time, the ruler of the ancient Egypt ordered the workers of Hanoi Factory to create as high tower as possible. They were not ready to serve such a strange order so they had to create this new tower using already produced rings.
There aren rings in factory's stock. Thei-th ring has inner radiusai, outer radius bi and height hi. The goal is to select some subset of rings and arrange them such that the following conditions are satisfied:
- Outer radiuses form a non-increasing sequence, i.e. one can put thej-th ring on thei-th ring only ifbj ≤ bi.
- Rings should not fall one into the the other. That means one can place ringj on the ringi only ifbj > ai.
- The total height of all rings used should be maximum possible.
The first line of the input contains a single integern (1 ≤ n ≤ 100 000) — the number of rings in factory's stock.
The i-th of the nextn lines contains three integersai,bi and hi (1 ≤ ai, bi, hi ≤ 109,bi > ai) — inner radius, outer radius and the height of the i-th ring respectively.
Print one integer — the maximum height of the tower that can be obtained.
解题思路:首先很容易想到要按照题目要求将这些圆环排一个序。首先保证外径要逐渐递减,其次要保证外径相同时,内径大的要放在下面。通过这样的序列可以保证如果有一个圆环不能放到当前的序列中了,那么在这之后的所有圆环都不能放在这个序列里了。
所以只需要每次维护当前放置圆环的序列就可以得到所有满足题意的情况,分析可以知道这个序列满足栈的性质,后进先出,每次将当前圆环和栈顶元素判断如果可以放置,就加在当前栈的上面,如果不可以就把当前栈顶部元素删除,再继续重复这个判断的过程。时刻维护当前栈的总高度,和答案取较大值即可。
AC代码:
/*
@Author: wchhlbt
@Date: 2017/2/25
*/
#include <bits/stdc++.h>
#define Fori(x) for(int i=0;i<x;i++)
#define Forj(x) for(int j=0;j<x;j++)
#define maxn 100005
#define inf 0x3f3f3f3f
#define ONES(x) __builtin_popcount(x)
using namespace std;
typedef long long ll ;
const double eps =1e-8;
const int mod = 1000000007;
typedef pair<int, int> P;
const double PI = acos(-1.0);
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
struct Node
{
int a,b,h;
}ring[maxn];
bool cmp(Node r, Node s)
{
if(r.b==s.b && r.a==s.a) return r.h>s.h;
else if(r.b==s.b) return r.a>s.a;
return r.b>s.b;
}
stack<Node> q;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i = 1; i<=n; i++)
cin>>ring[i].a>>ring[i].b>>ring[i].h;
sort(ring+1,ring+1+n,cmp);
ll ans = ring[1].h;
ll sum = ring[1].h;
q.push(ring[1]);
for(int i = 2; i<=n; i++)
{
while(!q.empty() && ring[i].b<=q.top().a)
{
sum -= q.top().h;
q.pop();
}
sum += ring[i].h;
q.push(ring[i]);
ans = max(ans,sum);
}
cout << ans << endl;
return 0;
}