UESTC_1558 Charitable Exchange 弦断树优化dp
来源:互联网 发布:淘宝精选在哪里 编辑:程序博客网 时间:2024/06/04 19:23
http://acm.uestc.edu.cn/problem.php?pid=1558
题意:
有N中交换的类型,每种交换都可以表示为(a ,b, c )表示的意思是用a元钱的东西,花上c的时间就可以将其变成价值为b的东西,数据保证a <= b ,初始时你有一件1元的东西,问你要使得最后的价值最起码是M,所要用的最少的时间是的多少。
思路:
这个题目如果数据量比较小的话是可以考虑用最短路做的,用最短路的话建图就需要O(N^2)的复杂度,所以这样是肯定不行的。我们考虑用dp来求。首先将所有的价值离散化,这样就变成了2*N个点,然后可以发现我们能获得的价值数一定是在某个交易的b ,这样我们就可以用dp[i]表示有i元的最少耗时(这里的i是离散化之后的i),这样dp的转移方程就是: dp[i] = min( dp[k] ) + exchange(j) ,其中exchange(j)的b等于i ,并且 exchange(j).a <= k <= exchange(j).b , 这样我们就可以发现,每次找决策点k的时候,就是在(a,b)内找一个dp的最小值,这样我们就可以用线段树在O(logn)的时间内找到该最小值,另外为了保持后效性,我们可以将每个exchange按照b的大小进行一次排序, 这样就可以顺序进行dp了。
代码:
#include<stdio.h>#include<string.h>#include<algorithm>typedef long long LL ;const int MAXN = 100010 ;int N , M ;LL T[MAXN<<1] ;const LL INF = 1e16 ;struct Point{ int s, e,t ; Point(){} Point(int a, int b ,int c) :s(a) , e(b) , t(c) {} bool operator<( const Point& cmp ) const { return e < cmp.e ; }}p[MAXN] ;LL min[MAXN<<3] ;int cnt ;inline LL MIN(LL a, LL b){ return a > b ? b : a ;}void update(int l ,int r, int idx, int pos, LL val ){ if(l == r){ min[idx] = MIN( min[idx] , val ); return ; } int mid = (l + r) >> 1 ; int ls = idx<<1 , rs = idx<<1|1 ; if( pos<=mid ) update(l , mid ,ls , pos , val ); else update(mid+1, r, rs , pos, val ); min[idx] = MIN( min[ls] , min[rs] );}int find(int v, int l ,int r){ while( l<r ){ int mid = (l + r) >> 1 ; if( T[mid] < v ) l = mid + 1 ; else r = mid ; } return l ;}LL query(int l, int r, int idx, int a, int b){ if(l==a && r==b){ return min[idx] ; } int mid = (l + r) >> 1 ; int ls = idx<<1 ,rs = idx<<1|1 ; if( b<=mid ) return query(l , mid , ls , a, b) ; else if( mid<a ) return query(mid+1, r, rs, a ,b ); else{ return MIN( query(l ,mid, ls , a ,mid ) , query(mid+1, r ,rs , mid+1, b) ); }}void build(int l , int r, int idx){ min[idx] = INF ; if(l == r) { return ; } int mid = (l + r) >> 1 ; int ls = idx<<1 , rs = idx<<1|1 ; build(l , mid ,ls ) ; build(mid+1, r, rs) ;}void solve(int n){ build(0, n ,1 ); update(0 , n ,1 ,0 , 0); for(int i=0;i<N;i++){ int s = p[i].s ; int e = p[i].e ; LL tt = p[i].t ; LL _min = query(0 , n ,1 , s , e ); if( _min == INF ) continue ; update(0 , n ,1 , e , _min+tt ) ; } int pos = find(M , 0 , n ); LL ans = query(0 , n , 1 ,pos, n ) ; if( ans == INF ) printf("-1\n"); else printf("%lld\n",ans);}int main(){ int TT , a, b, c ; scanf("%d",&TT); for(int cas=1;cas<=TT;cas++){ scanf("%d %d",&N,&M); cnt = 0 ; for(int i=0;i<N;i++){ scanf("%d %d %d",&a,&b,&c); p[i] = Point(b ,a ,c ); T[cnt++] = b ; T[cnt++] = a ; } T[cnt++] = M ; T[cnt++] = 1 ; //一开始NC地没加这个点,WA了N次。。。 std::sort(T, T+cnt ) ; int n = 0 ; for(int i=1;i<cnt;i++){ if( T[i]!=T[i-1] ) T[++n] = T[i] ; } for(int i=0;i<N;i++){ p[i].s = find( p[i].s , 0 , n ) ; p[i].e = find( p[i].e , 0 , n ) ; } std::sort(p ,p + N) ; printf("Case #%d: ",cas); solve(n); } return 0;}
- UESTC_1558 Charitable Exchange 弦断树优化dp
- uestc 482 Charitable Exchange 广搜+优先队列优化
- UESTC 1558 Charitable Exchange
- UESTC 1558 Charitable Exchange
- UESTC 482 Charitable Exchange
- 最短路,前缀和优化连边,Dijkstra(UESTC 482,Charitable Exchange)
- UESTC 482 Charitable Exchange (线段树)
- UESTC 482 Charitable Exchange(优先队列+bfs)
- 四川省ACM省赛B题,优先队列+BFS Charitable Exchange
- UESTC 482 Charitable Exchange(四川省赛B题)
- OpenJudge_P2421 Exchange Rates(DP)
- Exchange磁盘性能优化
- Exchange磁盘性能优化
- Exchange磁盘性能优化
- Exchange磁盘性能优化
- Exchange磁盘性能优化
- Exchange磁盘性能优化
- Exchange磁盘性能优化
- 什么叫代码覆盖率
- net面试问答(大汇总)
- net技术类面试、笔试题汇总
- android中阿拉伯文研究
- 切换用户登陆
- UESTC_1558 Charitable Exchange 弦断树优化dp
- VC程序需要的集合类
- C++学习笔记之一智能指针
- mars老师[Android开发视频教学] 01_21 广播机制(1)
- 少即是极多
- 黑马程序员_Java学习日记5_面向对象总结4
- 相见恨晚
- fish 编译安装问题
- 数据库学习目录