Poj--3171(线段树,DP)
2014-12-07 12:31:31
思路:经典的区间覆盖DP,dp[i]表示[M,i]被覆盖的最小费用,转移方程:dp[i] = min(dp[i],dp[k] + fee[i]) (T1[i] - 1 <= k <= T2[i] - 1)
dp值用线段树维护,优化到nlogn。注意:题目中的时间有可能为0,所以如果以1为根建树的话,要把所有时间+1再处理。
1 /************************************************************************* 2 > File Name: 3171.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Sun 07 Dec 2014 01:42:24 AM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const ll INF = 1e16; 26 const int maxn = 90000; 27 28 int N,M,E; 29 ll dp[maxn]; 30 31 struct node{ 32 int st,ed,sl; 33 }t[100010]; 34 35 struct SegTree{ 36 ll t[maxn << 2]; 37 void Build(int p,int l,int r){ 38 t[p] = INF; 39 if(l == r) 40 return; 41 int mid = getmid(l,r); 42 Build(lp,l,mid); 43 Build(rp,mid + 1,r); 44 } 45 void Update(int a,ll c,int p,int l,int r){ 46 if(l == r){ 47 t[p] = min(t[p],c); 48 return; 49 } 50 int mid = getmid(l,r); 51 if(a <= mid) Update(a,c,lp,l,mid); 52 else Update(a,c,rp,mid + 1,r); 53 t[p] = min(t[lp],t[rp]); 54 } 55 ll Query(int a,int b,int p,int l,int r){ 56 if(a <= l && r <= b){ 57 return t[p]; 58 } 59 int mid = getmid(l,r); 60 ll res = INF; 61 if(a <= mid) res = min(res,Query(a,b,lp,l,mid)); 62 if(b > mid) res = min(res,Query(a,b,rp,mid + 1,r)); 63 return res; 64 } 65 }ST; 66 67 bool cmp(node a,node b){ 68 return a.ed < b.ed; 69 } 70 71 int main(){ 72 scanf("%d%d%d",&N,&M,&E); 73 for(int i = 0; i < maxn; ++i) 74 dp[i] = INF; 75 ST.Build(1,1,maxn); 76 ++M; 77 ++E; 78 for(int i = 1; i <= N; ++i){ 79 scanf("%d%d%d",&t[i].st,&t[i].ed,&t[i].sl); 80 ++t[i].st; 81 ++t[i].ed; 82 } 83 sort(t + 1,t + N + 1,cmp); 84 for(int i = 1; i <= N; ++i){ 85 if(t[i].st > E || t[i].ed < M) 86 continue; 87 if(t[i].st <= M){ 88 dp[t[i].ed] = min(dp[t[i].ed],(ll)t[i].sl); 89 } 90 else{ 91 int bot = max(t[i].st - 1,M),top = min(E,max(t[i].ed - 1,M)); 92 ll tmin = ST.Query(bot,top,1,1,maxn); 93 dp[t[i].ed] = min(dp[t[i].ed],tmin + t[i].sl); 94 } 95 ST.Update(t[i].ed,dp[t[i].ed],1,1,maxn); 96 } 97 if(dp[E] >= INF) printf("-1\n"); 98 else printf("%I64d\n",dp[E]); 99 return 0; 100 }