比赛的时候,一开始写了个二维最朴素的dp,果断TLE。。然后就不知道怎么优化了。。。比完赛听某大佬学长说,先离散化,再树状数组维护一下y坐标,降维成一维的dp。
之前一直没学过离散化和树状数组,现在看来得学了QAQ...附上讲解博客Orz:
离散化:https://blog.csdn.net/xiangaccepted/article/details/73276826
树状数组:https://www.cnblogs.com/acgoto/p/8583952.html
具体思路就不说了,直接上AC代码吧:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX=1e5+5;
int n;
struct point
{
int x,y;
int val;
int id;
}p[MAX];
int tmp[MAX];
int dp[MAX];
int c[MAX];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val)
{
while(x<=n)
{
c[x]=max(c[x],val);
x+=lowbit(x);
}
}
int quary(int x)
{
int ans=0;
while(x>0)
{
ans=max(ans,c[x]);
x-=lowbit(x);
}
return ans;
}
bool cmp(struct point a,struct point b)
{
if(a.x==b.x)
return a.y<b.y;
else
return a.x<b.x;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(p,0,sizeof(p));
memset(tmp,0,sizeof(tmp));
memset(dp,0,sizeof(dp));
memset(c,0,sizeof(c));//注意清空
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].val);
tmp[i]=p[i].y;
}
//离散化
sort(tmp+1,tmp+1+n);
int tol=unique(tmp+1,tmp+1+n)-tmp-1;
for(int i=1;i<=n;i++)
p[i].y=lower_bound(tmp+1,tmp+1+tol,p[i].y)-tmp;
sort(p+1,p+1+n,cmp);
int ans=0,pos=1;
for(int i=1;i<=n;i++)
{
while(pos<i&&p[pos].x<p[i].x)//注意必须有判断小于x的条件
{
update(p[pos].y,dp[pos]);
pos++;
}
dp[i]=quary(p[i].y-1)+p[i].val;
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
}
return 0;
}