bzoj 2131: 免费的馅饼
易得方程 $f[i]=max(f[j])+v[i]$,条件是 $t[i]<t[j]$ 且 $2t[j]-x[j]<=2t[i]-x[i]$ 且 $2t[j]+x[j]<=2t[i]+x[i]$
一共有 3 个条件,但是你发现如果满足后面两个条件,自然满足第一个条件.
所以可以将问题转化为一个二位偏序问题,离线+树状数组处理一下即可.
code:
#include <bits/stdc++.h> #define N 100007 #define LL long long using namespace std; void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); // freopen(out.c_str(),"w",stdout); } struct data { int t,x,v,key1,key2; }a[N]; bool cmp(data a,data b) { return a.key1<b.key1; } int C[N],A[N],f[N]; int lowbit(int t) { return t&(-t); } void update(int x,int v) { for(;x<N;x+=lowbit(x)) C[x]=max(C[x],v); } int query(int x) { int ans=0; for(;x;x-=lowbit(x)) ans=max(ans, C[x]); return ans; } int main() { // setIO("input"); int w,n,i,j,ans=0; scanf("%d%d",&w,&n); for(i=1;i<=n;++i) { scanf("%d%d%d",&a[i].t,&a[i].x,&a[i].v); a[i].key1=2*a[i].t-a[i].x; a[i].key2=2*a[i].t+a[i].x; A[i]=a[i].key2; } sort(A+1,A+1+n); for(i=1;i<=n;++i) a[i].key2=lower_bound(A+1,A+1+n,a[i].key2)-A; sort(a+1,a+1+n,cmp); for(i=1;i<=n;++i) { f[i]=query(a[i].key2)+a[i].v; update(a[i].key2,f[i]); ans=max(ans,f[i]); } printf("%d\n",ans); return 0; }