poj3171Cleaning Shifts-dp/线段树

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<iomanip>
 8 using namespace std;
 9 namespace Moxing {
10     const int N=10000+20;
11     const int M=86399+20;
12     const int inf=0x3f3f3f3f;
13     int n,L,R,f[M];
14     struct node {
15         int l,r,minn;
16     } tree[M<<2];
17     struct nod {
18         int l,r,val;
19     } a[N];
20     bool cmp(nod x,nod y) {
21         return x.r<y.r;
22     }
23     void pushup(int tr) {
24         tree[tr].minn=min(tree[tr<<1].minn,tree[tr<<1|1].minn);
25     //    cout<<tree[tr].l<<' '<<tree[tr].r<<' '<<tree[tr].minn<<endl;
26     }
27     void change(int tr,int pos,int d) {
28         if(tree[tr].l==tree[tr].r) {
29             //cout<<'&'<<tree[tr].l<<' '<<tree[tr].r<<' '<<d<<endl;
30             tree[tr].minn=d;
31             return ;
32         }
33         int mid=(tree[tr].l+tree[tr].r)>>1;
34         if(pos<=mid) change(tr<<1,pos,d);
35         else change(tr<<1|1,pos,d);
36         pushup(tr);
37         //cout<<tree[tr].minn<<endl;
38         return ;
39     }
40     int query(int tr,int l,int r) {
41         if(tree[tr].l>r||tree[tr].r<l) return inf;
42         if(tree[tr].l>=l&&tree[tr].r<=r){
43         //    puts("query");
44         //    cout<<tree[tr].l<<' '<<tree[tr].r<<' '<<tree[tr].minn<<endl;
45             return tree[tr].minn;
46         }
47     //    int mid=(tree[tr].l+tree[tr].r)>>1;
48         //if(r<=mid) return query(tr<<1,l,r);
49         //else if(l>mid) return query(tr<<1|1,l,r);
50         return min(query(tr<<1,l,r),query(tr<<1|1,l,r));
51     }
52     void build(int tr,int l,int r) {
53         tree[tr].r=r,tree[tr].l=l,tree[tr].minn=inf;
54         if(l==r) {
55             return ;
56         }
57         int mid=(l+r)>>1;
58         build(tr<<1,l,mid),build(tr<<1|1,mid+1,r);
59     }
60     struct main {
61         main() {
62             scanf("%d%d%d",&n,&L,&R);
63             L+=2,R+=2;
64 
65             for(int i=1; i<=n; i++) {
66                 scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].val);
67                 a[i].l+=2,a[i].r+=2;
68             }
69             build(1,1,M);
70             memset(f,0x3f,sizeof(f));
71             f[L-1]=0;
72             change(1,L-1,0);//cout<<query(1,L-1,L-1)<<endl;
73             sort(a+1,a+1+n,cmp);
74         //    cout<<endl<<L<<' '<<R<<endl;
75             
76             for(int i=1; i<=n; i++) {
77                 if(a[i].r<L) continue ;
78                 //    cout<<query(1,a[i].l-1,a[i].r)<<' ';
79                 //cout<<a[i].l-1<<' '<<a[i].r<<' '<<query(1,a[i].l-1,a[i].r)<<endl;
80                 int tmp=query(1,a[i].l-1,a[i].r)+a[i].val;
81                 //    cout<<tmp<<' ';
82                 if(f[a[i].r]>tmp) {
83                     f[a[i].r]=tmp;
84                     change(1,a[i].r,f[a[i].r]);
85                 }
86             }
87             int ans=inf;
88             for(int i=R; i<M; i++) {
89                 ans=min(ans,f[i]);
90             }
91             cout<<(ans==inf?-1:ans)<<endl;
92             exit(0);
93         }
94     } UniversalLove;
95 }
96 int main() {
97     Moxing::main();
98 }
View Code

设f[x]表示覆盖[L,x]最小代价,将N个贴纸按r递增排序,f[r[i]]=min(f[x])+val[i];x:[l[i],r[i]]

---------

query函数在写的时候第一句不小心写成了 if(tree[tr].l>l  ||  tree[tr].r<r) return inf;  查了好半天。

虽然这几天压力很大 写题还是要平静下来,熟练了就会少犯错。

猜你喜欢

转载自www.cnblogs.com/Moxingtianxia/p/11300314.html