csu:1922: Irony Ring
来源:互联网 发布:java错误调试 编辑:程序博客网 时间:2024/04/29 09:39
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
题目意思很好理解
思路:
其实这道题因为跟紫书的一道题比较像,所以一直往dp上想,就是先排个序,然后按照LIS写,其实这个思路是没错的,但是数据量太大,如果用n^2的求法,必超时,但是如果用nlogn的求法的话,虽然时间复杂度上能过去,但是由于nlogn的求法时d[len] = a[i] 的思想,就是利用二分找到长度len的最好的值,如果把len当为高度的话,二分的时候就不满足了,每一次还要排个序(等等突然好像可以,等下试下),容易想到首先按照贪心的思想按照外半径从到到小排序,当外半径相同时我们就按照内半径从大到小排列, 那么
为什么要这样排序呢,因为按照外半径从大到小的话,我们就不用考虑前一个的外半径对后面的影响,就相当于消除的一个因素,接下来为什么当外半径相同时按照内半径从大到小排列,因为当第一个满足条件的时候,后面相同的外半径一定满足条件,所以要保证最后一个的内半径尽量小,这样才能放的更高。然后我们开一个栈存储当前的已经堆起来的,然后对于当前要放的戒指,如果不行不能放的话,去掉堆栈顶直到能放为止,因为当前这个不能放的话后面的肯定也不能放,更新最大值即可
ac代码:
#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<sstream>#include<stack>#include<queue>#define LL long longusing namespace std;const int maxn = 1e5+10;int n;struct node{ long long in,out,h;}t[maxn];int cmp(node a,node b){ if(a.out==b.out) return a.in>b.in; return a.out>b.out;}int main(){ while(~scanf("%d",&n)) { for(int i = 0 ;i < n;i++) { scanf("%lld%lld%lld",&t[i].in,&t[i].out,&t[i].h); } sort(t,t+n,cmp); stack<node> Q; LL sum = t[0].h; Q.push(t[0]); LL ans = sum; for(int i = 1 ;i < n;i++) { while(!Q.empty()&&t[i].out<=Q.top().in) { sum -= Q.top().h; ans = max(ans,sum); Q.pop(); } sum += t[i].h; ans = max(ans,sum); Q.push(t[i]); } cout<<ans<<endl; } return 0;}
- csu:1922: Irony Ring
- CSU 1922:Irony Ring(贪心算法)
- CSU 1922 Irony Ring 类似单调栈的瞎搞或者线段树
- CSUOJ 1922 Irony Ring 线段树 or 贪心
- Irony - .NET 学习笔记
- Ring
- ring
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- 1021. Deepest Root (25)
- 隐藏键盘windowSoftInputMode
- Mybatis常见面试题
- iOS GPUImage 的使用
- 个人感觉好用的sharedpreference工具类写法
- csu:1922: Irony Ring
- 【easyui】datagrid横向滚动条自动滚动功能
- 204. Count Primes(C++)
- 0156 java中的WeakReference
- 字符串格式化format符号含义+转义字符含义
- 算法导论——26.2 FordFulkerson方法,Edmonds-Karp算法java实现
- 有一个和尚负责做馒头,做好30个其它三个和尚就可以吃馒头, *当馒头吃完了,第一个和尚就再做30个馒头 生产消费
- 1026. 程序运行时间(15)
- 阻止事件冒泡,嵌套元素事件加载互不影响