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

浙公网安备 33010602011771号