CSU 1922:Irony Ring(贪心算法)

1922: Irony Ring
        Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 101     Solved: 25    

Description

There are n irony ring in a factory. The i-th ring has inner radius ai, outer radius bi and height hi. The goal is to select some subset of irony ring to create as high town as possible . The subset of irony ring following condition are satisifed:
  • 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;
  • the above ring’s outer radius should longer than the below ring’s inner radius. That means one can place ring j on the ring i only if bj>ai.
  • The total height of ring used should be maximum possible.

Input

The first line contain a integer n ( 1<=n<=100000 )--the number of irony ring in the factory. The i-th line of the next n lines contains three integers ai, bi, hi ( 1<=ai, bi, hi<=10^ 9, ai<bi )--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.

Sample Input

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

Sample Output

6
4

Hint

In the first sample, the optimal solution is to take all the ring and put them on each other in order 3 2 1 In the second sample, one can put 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.

Source

Author

王树帆



        这题不想多说了,连贪心的题目都能想不到。
        题意就是给你圆环零件,每个有高度。问你最高能够叠多高?
        当时也想得到,应该是一个贪心,而且也想到了类似一个最长不下降子串那样的贪心策略。但是没想到这个用一个栈就可解决(当时觉得要用好多个栈)。然后之后知道了开始自己打,发现错了T_T……最后终于发现原来顺序也是有讲究的,才算是A了。
        具体贪心策略的话,就是按照先外半径后内半径从大到小排序,之后维护一个栈,先进栈的圆环在下面,然后如果能直接放在栈顶圆环的上面,就直接放,否则一只退栈知道能够放下。在处理每一个圆环的时候实时记录栈的总高度,并更新ans。
        我相信以外半径为第一关键字不用我解释了,主要讲讲为什么内半径也要从大到小。如果内半径无序或者从小到大,那么有可能出现这种情况:圆环i和i+1外半径相同,但内半径i更小,而i+2的外半径恰好与i+1的内半径相同。这意味着我们本可以以i+1、i、i+2的顺序叠,但是由于i先进栈,i+1后进栈,无法达到这种情况,导致策略错误。另一方面,我们一定要从下往上的放圆环,相应的要从大到小排序,我在a之前写了一个从下往上从小到大的,结果wa了。这个的话,其实也好说,例如可能出现i无法放在圆环i-1下面,这时候我们会把i-1退栈,然而,可能i之后的原盘可以放在i-1下面,但是i-1已经永远的退栈了,又会导致策略错误。综上,目前这种贪心策略是唯一的。

        其实,贪心算法也是博大精深的,不要以为他很简单,很多时候要考虑的东西还是很多的。具体代码如下:

#include<bits/stdc++.h>
using namespace std;

struct Ring
{
	int in,ot,h;
} r[101000];

bool operator <(const Ring a,const Ring b)
{
	return a.ot==b.ot?a.in>b.in:a.ot>b.ot;
}

int main()
{
	int n;
	while (~scanf("%d",&n))
	{
		for(int i=1;i<=n;i++)
			scanf("%d%d%d",&r[i].in,&r[i].ot,&r[i].h);
		sort(r+1,r+n+1);
		stack<Ring> sta;
		sta.push(r[1]);
		long long ans=r[1].h,h=r[1].h;
		for(int i=2;i<=n;i++)
		{
			while (!sta.empty()&&sta.top().in>=r[i].ot)
			{
				h-=sta.top().h; sta.pop();
			}
			sta.push(r[i]);
			h+=r[i].h;
			ans=max(ans,h);
		}
		printf("%lld\n",ans);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值