CSU 1922:Irony Ring(贪心算法)

来源:互联网 发布:数据修复图片 编辑:程序博客网 时间:2024/04/30 22:25
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

31 5 12 6 23 7 341 2 11 3 34 6 25 7 1

Sample Output

64

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

0 0
原创粉丝点击