假设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;
}