codeforces 777E Hanoi Factory (栈+贪心)

题目原文: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.
Input

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.

Output

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值