bzoj 1537 [POI2005]Aut- The Bus(DP+BIT)

【题意】

    顺序经过k个点,求获得的最大权值和。

【思路】

    设f[i]表示到第i个点,则有转移式:

        f[i]=min{ f[j]+w[i] } x[j]<=x[i],y[j]<=y[i]

    满足的条件是一个二维偏序,可以将x排序后用BIT维护y区间上的最大值。

    又因为y比较大,所以需要提前离散化y坐标。

【代码】

 1 #include<set>
 2 #include<cmath>
 3 #include<queue>
 4 #include<vector>
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
11 using namespace std;
12 
13 typedef long long ll;
14 const int N = 5e5+10;
15 
16 ll read() {
17     char c=getchar();
18     ll f=1,x=0;
19     while(!isdigit(c)) {
20         if(c=='-') f=-1; c=getchar();
21     }
22     while(isdigit(c))
23         x=x*10+c-'0',c=getchar();
24     return x*f;
25 }
26 
27 ll C[N],tot;
28 void upd(int x,ll v) 
29 {
30     for(;x<=tot;x+=x&-x) 
31         C[x]=max(C[x],v);
32 }
33 ll query(int x) 
34 {
35     ll res=0;
36     for(;x;x-=x&-x)
37         res=max(res,C[x]);
38     return res;
39 }
40 
41 struct Node {
42     int x,y,z;
43     bool operator < (const Node& rhs) const{
44         return x<rhs.x||(x==rhs.x&&y<rhs.y);
45     }
46 }ns[N];
47 
48 int r,c,n;
49 int hash[N*3];
50 
51 int main()
52 {
53     //freopen("in.in","r",stdin);
54     //freopen("out.out","w",stdout);
55     r=read(),c=read(),n=read();
56     FOR(i,1,n) {
57         ns[i].x=read(),ns[i].y=read(),ns[i].z=read();
58         hash[++tot]=ns[i].x,hash[++tot]=ns[i].y;
59     }
60     sort(hash+1,hash+tot+1);
61     tot=unique(hash+1,hash+tot+1)-hash-1;
62     FOR(i,1,n)
63         ns[i].y=lower_bound(hash+1,hash+tot+1,ns[i].y)-hash;
64     sort(ns+1,ns+n+1);
65     ll ans=0;
66     FOR(i,1,n) {
67         ll x=query(ns[i].y)+ns[i].z;
68         ans=max(ans,x);
69         upd(ns[i].y,x);
70     }
71     printf("%d",ans);
72     return 0;
73 }
原文地址:https://www.cnblogs.com/lidaxin/p/5297116.html