Input
50 3 1 49 1 1 26 1 4 6 1 10
Output
-31
因为只要用到上层一段(贴着 j ),所以缩空间为 f [2][N];
ac代码:
#include<iostream>
#define ll long long
using namespace std;
const int N=150010;
const int M=310;
int n,m,d;
ll a[M],b[M],t[M];
ll f[2][N],q[N];
int main(){
cin>>n>>m>>d;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a[i],&b[i],&t[i]);
}
for(int i=1;i<=m;i++){
int h=0,t1=-1;
int now=i%2,fom=(i+1)%2;
ll d1=d*(t[i]-t[i-1]);
//可写 可不写 写了快点
// if(d1==0){
// for(int j=1;j<=n;j++)
// f[now][j]=f[fom][j]+b[i]-(abs(a[i]-j));
// continue;
// }
for(int j=1;j<=d1+1&&j<=n;j++){
while(h<=t1&&f[fom][j]>=f[fom][q[h]]) t1--;
q[++t1]=j;
}
for(int j=1;j<=n;j++){
if(h<=t1&&abs(j-q[h])>d1) h++;
f[now][j]=f[fom][q[h]]+b[i]-(abs(a[i]-j));
if((j+d1+1)<=n){
while(h<=t1&&f[fom][j+d1+1]>=f[fom][q[h]]) t1--;
q[++t1]=j+d1+1;
}
}
}
ll ans=-1e18;
int now=m%2;
for(ll i=1;i<=n;i++){
ans=max(ans,f[now][i]);
}
printf("%I64d",ans);
return 0;
}