[POI2005]AUT-The Bus
Posted cold-cold
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POI2005]AUT-The Bus相关的知识,希望对你有一定的参考价值。
题目描述:
Byte City 的街道形成了一个标准的棋盘网络 – 他们要么是北南走向要么就是西东走向. 北南走向的路口从 1 到 n编号, 西东走向的路从1 到 m编号. 每个路口用两个数(i, j) 表示(1 <= i <= n, 1 <= j <= m). Byte City里有一条公交线, 在某一些路口设置了公交站点. 公交车从 (1, 1) 发车, 在(n, m)结束.公交车只能往北或往东走. 现在有一些乘客在某些站点等车. 公交车司机希望在路线中能接到尽量多的乘客.帮他想想怎么才能接到最多的乘客.
看完题目后我很高兴,我以为这是到大水题,只不就是一个O(nm)的DP嘛,有什么难的。但当我看到数据范围1≤n≤109, 1≤m≤109, 1≤k≤105 的时候,我就笑不出来了,我立刻想到这一定是一个O(k2)的DP,通过数据结构优化为O(klogk)
我首先想到的是将整张图按照与对角线平行的线分为n+m-1层,逐层递推,但我很快发现不行,(在笛卡尔坐标系下)如两个点(2,3)和(4,2) ,点2的所在层数比点1大1,按照我的方法点2应该可以从点1转移,但实际上不行,点1不能向下走到点2
然后我就想到了最长不下降子序列的树状数组优化法,我将x排序后,将y做一个最大子序列(注:不是最长不下降子序列)不就可以了吗?考虑到1≤m≤109所以要离散化
操作起来,就是dp[i]表示,以x排序后的以第i个点为最后一个节点所能达到的最大值
转移为在1 - (i-1)中找到y值不大于第i个点y值的点,在其中取最大值再加上p[i],就是dp[i]的值,树状数组优化法较为常见,就不再赘述
实现如下:
#include <algorithm> #include <iostream> #include <cmath> #include <cstring> #include <map> #include <string> #include <vector> #include <queue> #include <stack> #include <cstdio> #include <cstdlib> #define lowbit(x) x&-x using namespace std; typedef long long ll; inline int read() { register int p(1),a(0);register char ch=getchar(); while((ch<‘0‘&&ch>‘9‘)&&ch!=‘-‘) ch=getchar(); if(ch==‘-‘) p=-1,ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) a=a*10+ch-48,ch=getchar(); return a*p; } const int N=1000100; struct node { int x,y,p,hao; bool operator < (const node xx)const { return x==xx.x?y<xx.y:x<xx.x; } }a[N]; inline int max(int x,int y){return x<y?y:x;} int f[N],n,m,k,tt[N],maxn[N],len,ans=0,temp; void update(int p,int x) { for(int i=p;i<=len;i+=lowbit(i)) maxn[i]=max(x,maxn[i]); } int query(int p) { int ans=0; for(int i=p;i>=1;i-=lowbit(i)) ans=max(ans,maxn[i]); return ans; } int main() { n=read(),m=read(),k=read(); for(int i=1;i<=k;++i) a[i].x=read(),a[i].y=read(),a[i].p=read(); sort(a+1,a+1+k); for(int i=1;i<=k;++i) tt[i]=a[i].y; sort(tt+1,tt+1+k); len=unique(tt+1,tt+1+k)-tt-1; for(int i=1;i<=k;++i) a[i].hao=lower_bound(tt+1,tt+1+len,a[i].y)-tt-1; for(int i=1;i<=k;++i) { ans=max(ans,temp=a[i].p+query(a[i].y)); update(a[i].y,temp); } printf("%d ",ans); return 0; }
以上是关于[POI2005]AUT-The Bus的主要内容,如果未能解决你的问题,请参考以下文章
P3431 [POI2005]AUT-The Bus(二维偏序树状数组)
[BZOJ1537][POI2005]Aut- The Bus
Bzoj 1537: [POI2005]Aut- The Bus 题解 [由暴力到正解]