【线段树+dp】poj3171
题意:给n个区间及其代价值,问要覆盖[M,E]区间至少要花费多少代价
传送门:https://vjudge.net/problem/POJ-3171
其实就是一个很简单的dp:,dp[j]表示覆盖s到j最少费用,dp[j]=min{dp[j],dp[k](t1-1<=k<=t2-1)+cost[i]}。我是对右端点排序,然后这样就保证每次更新的顺序了。具体看代码吧。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // Cease to struggle and you cease to live 2 #include <iostream> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #include <queue> 8 #include <vector> 9 #include <set> 10 #include <map> 11 #include <stack> 12 using namespace std; 13 typedef long long ll; 14 const int inf=0x3f3f3f3f; 15 struct node{ 16 int l,r,v; 17 bool operator<(const node& b)const{ 18 return r<b.r; 19 } 20 }a[10000+9]; 21 int tr[880000]; 22 void build(int l,int r,int o){ 23 if(l==r){ 24 tr[o]=inf; 25 return; 26 } 27 int m=(l+r)/2; 28 build(l,m,o<<1); 29 build(m+1,r,o<<1|1); 30 tr[o]=min(tr[o<<1],tr[o<<1|1]); 31 return; 32 } 33 int query(int l,int r,int o,int x,int y){ 34 if(x<=l && r<=y) return tr[o]; 35 int m=(l+r)>>1; 36 int ans=inf; 37 if(x<=m) ans=min(ans,query(l,m,o<<1,x,y)); 38 if(y>m) ans=min(ans,query(m+1,r,o<<1|1,x,y)); 39 return ans; 40 } 41 void update(int l,int r,int o,int x,int v){ 42 if(l==r){ 43 tr[o]=v; 44 return; 45 } 46 int m=(l+r)>>1; 47 if(x<=m) update(l,m,o<<1,x,v); 48 else update(m+1,r,o<<1|1,x,v); 49 tr[o]=min(tr[o<<1],tr[o<<1|1]); 50 } 51 int main() { 52 int n,s,t;scanf("%d%d%d",&n,&s,&t); 53 t-=s-2; 54 for(int i=1;i<=n;++i){ 55 scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].v); 56 a[i].l-=s-2; 57 a[i].r-=s-2; 58 } 59 s=2; 60 sort(a+1,a+1+n); 61 build(1,t,1); 62 update(1,t,1,1,0); 63 //update(1,t,1,2,0); 64 for(int i=1;i<=n;++i){ 65 int tem=query(1,t,1,a[i].l-1,a[i].r-1); 66 int ini=query(1,t,1,a[i].r,a[i].r); 67 if(tem+a[i].v<ini) update(1,t,1,a[i].r,tem+a[i].v); 68 } 69 int ans=query(1,t,1,t,t); 70 if(ans==inf) puts("-1"); 71 else printf("%d",ans); 72 return 0; 73 }