BZOJ1537: [POI2005]Aut- The Bus
题目是让求 f[i] = max{f[j]} + v[i] (x[i] >= x[j] && y[i] >= y[j])
按 x 排序后就是把条件 x[i] >= x[j] 变成了 i > j
这样就比较可做了
离散化 y
从小到大枚举 i ,用数据结构维护 1~y[i] 中的点中 max(f[j])
可以用树状数组因为是维护前缀max并且值不会变小
直接转移就行
方便统计答案就加了一个坐标为 (n, m) 点权为 0
代码:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cctype> #include<cstdio> using namespace std; const int MAXN = 100005; struct Node{ int x, y, uy, val; bool operator < (const Node& b) const { return ((x == b.x) ? (y < b.y) : (x < b.x)); } }pt[MAXN]; int n, m, k, sizu; int uni[MAXN], f[MAXN], bit[MAXN]; inline void update(int x, int val) { for( ; x <= sizu; x += (x & -x)) bit[x] = max(bit[x], val); return; } inline int query(int x) { register int ret = 0; for( ; x > 0; x -= (x & -x)) ret = max(ret, bit[x]); return ret; } int main() { scanf("%d%d%d", &n, &m, &k); for(int i = 1; i <= k; ++i) { scanf("%d%d%d", &pt[i].x, &pt[i].y, &pt[i].val); uni[i] = pt[i].y; } ++k; pt[k].x = n; pt[k].y = m; pt[k].val = 0; uni[k] = m; sort(uni + 1, uni + k + 1); sizu = unique(uni + 1, uni + k + 1) - uni - 1; for(int i = 1; i <= k; ++i) pt[i].uy = lower_bound(uni + 1, uni + sizu + 1, pt[i].y) - uni; sort(pt + 1, pt + k + 1); for(int i = 1; i <= k; ++i) { f[i] = query(pt[i].uy) + pt[i].val; update(pt[i].uy, f[i]); } printf("%d\n", f[k]); return 0; }
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/