题目传送门:http://acm.scu.edu.cn/soj/problem.action?id=4513
长度n的一条路,有m个地点放烟花,然后每个烟花在地点
ai
,有好看度
bi
,然后一个烟花对幸福感的贡献值为
bi−|ai−cur|
,其中cur为当前人在的地点,然后人有个速度
d
,每个烟花放的也有时间间隔,问你能够获得的最大幸福感是多少
幸福感的贡献值可以先把
考虑状态
dp[i][j]
表示放第
i
个烟花的时候,人站在地点
代码:
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
#define MAX 305
#define MAXN 150005
#define maxnode 15
#define sigma_size 30
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lrt rt<<1
#define rrt rt<<1|1
#define middle int m=(r+l)>>1
#define LL long long
#define ull unsigned long long
#define mem(x,v) memset(x,v,sizeof(x))
#define lowbit(x) (x&-x)
#define pii pair<int,int>
#define bits(a) __builtin_popcount(a)
#define mk make_pair
#define limit 10000
//const int prime = 999983;
const int INF = 0x3f3f3f3f;
const LL INFF = 0x3f3f;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-8;
const LL mod = 1e9+7;
const ull mx = 133333331;
/*****************************************************/
inline void RI(int &x) {
char c;
while((c=getchar())<'0' || c>'9');
x=c-'0';
while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';
}
/*****************************************************/
int a[MAX];
int b[MAX];
int t[MAX];
LL dp[2][MAXN];
int deq[MAXN];
LL deqv[MAXN];
int main(){
//freopen("in.txt","r",stdin);
int T;
cin>>T;
while(T--){
int n,m,d;
scanf("%d%d%d",&n,&m,&d);
LL sum=0;
int cur=0;
LL mini=1e18;
for(int i=1;i<=m;i++){
RI(a[i]),RI(b[i]),RI(t[i]);
sum+=b[i];
cur^=1;
int head=0,tail=0;
int tot=1;
for(int j=1;j<=n;j++){
if(i==1){
dp[cur][j]=abs(a[i]-j);
}
else{
while(tot<=min((LL)n,(LL)j+(LL)d*(t[i]-t[i-1]))){
while(tail>head&&deqv[tail-1]>=dp[cur^1][tot]) tail--;
deq[tail]=tot;
deqv[tail++]=dp[cur^1][tot];
tot++;
}
dp[cur][j]=deqv[head]+abs(a[i]-j);
if((LL)j-(LL)d*(t[i]-t[i-1])==deq[head]) head++;
}
}
if(i==m){
for(int j=1;j<=n;j++) mini=min(mini,dp[cur][j]);
}
}
cout<<sum-mini<<endl;
}
return 0;
}