solve
- 首先,们可以将题目转化为类似此题:Fire(有区别但是差不多但是不能这么解),考虑dp
- 转移方程:dp[i]=max(dp[i],dp[j]+v[i]);
- 此时应满足:2×(t[i]−t[j]) ≥ | p[i]−p[j] |;
- 容易发现需要两层循环,时间复杂度为O($n2$),而**n=$105$**,超时
- 考虑用数据结构优化
- 对于上述满足dp条件的不等式,我们进行化简得出:
- 当p[i]≥p[j]时,有:p[j] - 2 * t[j] ≥ p[i] - 2 * t[i];
- 当p[i]<p[j]时,有:p[i] + 2 * t[i] ≥ p[j] + 2 * t[j];
- 对于上述两个不等式,一个用于排序,一个用于算a[i].x
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int w,n;
int c[maxn];
int dp[maxn];
int sum[maxn];
int ans;
struct node
{
int t,p,v,x;
}a[maxn];
bool cmp (node nd1,node nd2){return nd1.p-2*nd1.t>=nd2.p-2*nd2.t;}
int lowbit(int x){return (x&(-x));}
void add(int w,int x)
{
while(w<=n)
{
c[w]=max(c[w],x);
w+=lowbit(w);
}
}
int query(int w)
{
int res=0;
while(w)
{
res=max(res,c[w]);
w-=lowbit(w);
}
return res;
}
int main()
{
cin >> w >> n;
for (int i=1;i<=n;i++)
{
cin >> a[i].t >> a[i].p >> a[i].v;
sum[i]=2*a[i].t+a[i].p;
}
sort (sum+1,sum+1+n);
for (int i=1;i<=n;i++)
{
a[i].x=lower_bound(sum+1,sum+1+n,2*a[i].t+a[i].p)-sum;
}
sort(a+1,a+1+n,cmp);
for (int i=1;i<=n;i++)
{
dp[i]=query(a[i].x)+a[i].v;
add(a[i].x,dp[i]);
ans = max(ans,dp[i]);
}
cout << ans << endl;
return 0;
}