当前位置: 代码迷 >> 综合 >> codeforces 777E 单调栈 greedy
  详细解决方案

codeforces 777E 单调栈 greedy

热度:58   发布时间:2023-12-12 17:37:26.0

传送门:https://codeforces.com/problemset/problem/777/E

E. Hanoi Factory

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

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 are n rings in factory's stock. The i-th ring has inner radius ai, 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 the j-th ring on the i-th ring only if bj?≤?bi.
  • Rings should not fall one into the the other. That means one can place ring j on the ring i only if bj?>?ai.
  • The total height of all rings used should be maximum possible.

Input

The first line of the input contains a single integer n (1?≤?n?≤?100?000) — the number of rings in factory's stock.

The i-th of the next n lines contains three integers aibi and hi (1?≤?ai,?bi,?hi?≤?109, bi?>?ai) — inner radius, outer radius and the height of the i-th ring respectively.

Output

Print one integer — the maximum height of the tower that can be obtained.

Examples

input

Copy

3
1 5 1
2 6 2
3 7 3

output

Copy

6

input

Copy

4
1 2 1
1 3 3
4 6 2
5 7 1

output

Copy

4

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.

会给你n个圆环,并且告知他们的内环半径和外环半径,以及他们的高,问你怎么摆放可以使得高度最高

摆放的要求如下: 如果讲j放在i上,那么要保证a[i] < b[j] && b[j] <= a[i]

第一想法可以直接排序,按b从大到小排序,当b相同的时候,就按a从大到小排序(因为可以观察到,b从大到小很容易可以得知,当b相同的时候,由于a[i] < b[j]这个条件,我们可以从大到小排序,可以知道,如果当前i的a是小于j的b才可以放在i上面),然后现在得到了一个近乎单调性的数组,接着用一个单调栈然后,每次入栈,判断栈顶和当前i的大小关系,是否不满足,不满足的话就出栈,出到满足位置(如果都不满足当前的i的话,那栈内的更不可能满足i + 1到n的圆盘,根据单调性可以得知),并且对于每次ans取个max即可,一A 

后面看tags也有dp的tag,但是目前还没不会dp的做法。。。(dp完全不会呜呜)

代码如下:

#include <bits/stdc++.h>
#include <time.h>
#define first fi
#define second seusing namespace std;typedef long long ll;
typedef double db;
int xx[4] = {1,-1,0,0};
int yy[4] = {0,0,1,-1};
const double eps = 1e-9;
typedef pair<int,int>  P;
const int maxn = 2e6 + 5000;
const ll mod = 1e9 + 7;
inline int sign(db a) { return a < -eps ? -1 : a > eps;}
inline int cmpp(db a,db b){ return sign(a - b);}
ll mul(ll a,ll b,ll c) { ll res = 1; while(b) {  if(b & 1) res *= a,res %= c;  a *= a,a %= c,b >>= 1;  }  return res;}
ll phi(ll x) {  ll res = x;  for(ll i = 2; i * i <= x; i++) { if(x % i == 0) res = x / i * (i - 1);   while(x % i == 0) x /= i;   }  if(x > 1) res = res / x  * (x - 1);    return res;}
ll c,n,k;
struct node{int a,b,h;
}g[maxn];
bool cmp(node a,node b){if(a.b == b.b) return a.a > b.a;return a.b > b.b;
}
int main() {ios::sync_with_stdio(false);while(cin >> n){stack<node>s;for(int i = 1;i <= n;i++) cin >> g[i].a >> g[i].b >> g[i].h ;sort(g + 1, g + 1 + n,cmp);ll ans = 0,num = 0;for(int i = 1;i <= n;i++){
//            cout << g[i].a << "  " << g[i].b << " " << g[i].h << endl;}for(int i = 1;i <= n;i++){if(!s.empty()){while(!s.empty() && (g[i].b <=  s.top().a || g[i].b > s.top().b)){num -= s.top().h;s.pop();}s.push(g[i]);num += g[i].h;ans = max(ans,(long long)num);}else s.push(g[i]),num += g[i].h,ans = max(ans,num);
//            cout << num << endl;}cout << ans << endl;}//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;return 0;
}