BZOJ1537/POI2005 The Bus

7 篇文章 0 订阅
2 篇文章 0 订阅

假设dp[i][j]表示在(i,j)位置能够接到的最多乘客数量,我们会发现很多的状态是无效的,因此只要记录到达站点的状态.由于只能向北或向东走,只可能通过西南的站点到达(i,j),也就是所有满足a<=i&&b<=j的站点(a,b).这样就有两维状态,可以通过排序+区间求值的方法降维.
我们可以按照横坐标从小到大排序,维护纵坐标的区间最值,由于每次求的是前缀最值并且不断增大,可以用树状数组求解.

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1e5+5;
int mx[M],n,a[M],tot=0,m,K;
inline void rd(int &res){
    res=0;char c;
    while(c=getchar(),c<48);
    do res=(res<<1)+(res<<3)+(c^48);
    while(c=getchar(),c>=48);
}
struct  node{
    int x,y,p;
    bool operator<(const node &tmp)const{
        if(y!=tmp.y)return y>tmp.y;
        return x>tmp.x;
    }
}s[M];
int findmx(int x){//
    int res=0;
    while(x<=tot){
        res=max(res,mx[x]);
        x+=x&-x;
    }
    return res;
}
void Up(int x,int v){
    while(x){
        mx[x]=max(mx[x],v);
        x-=x&-x;
    }
}
int main(){
    int i,j,k,x,y,z;
    rd(x);rd(y);rd(n);
    for(i=1;i<=n;i++){
        rd(s[i].x);rd(s[i].y);rd(s[i].p);
        a[i-1]=s[i].x;
    }
    sort(a,a+n);
    tot=unique(a,a+n)-a;
    for(i=1;i<=n;i++){
        s[i].x=lower_bound(a,a+tot,s[i].x)-a+1;
    }
    sort(s+1,s+1+n);
    for(i=1;i<=n;i++){
        int v=findmx(s[i].x);
        Up(s[i].x,v+s[i].p);
    }
    int ans=findmx(1);
    printf("%d\n",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值