E48 单调队列优化DP Watching Fireworks is Fun

E48 单调队列优化DP Watching Fireworks is Fun_哔哩哔哩_bilibili

 

CF372C Watching Fireworks is Fun - 洛谷

// 单调队列 O(nm)
#include<bits/stdc++.h>
using namespace std;

#define LL long long
const int N=150010,M=310;
LL n,m,d,a[M],b[M],ti[M];
LL f[2][N],q[N];

int main(){
  cin>>n>>m>>d; //n个位置,m个烟花,移动d个距离
  for(int i=1; i<=m; i++)cin>>a[i]>>b[i]>>ti[i]; //地点a,快乐b,时刻ti
  memset(f,-0x3f,sizeof(f));
  for(int i=1;i<=n;i++) f[0][i]=0;
  
  for(int i=1;i<=m;i++){ //第i烟花
    int now=i&1,last=(i-1)&1;
    for(int j=1,h=1,t=0;j<=n;j++){ //第j位置 窗口右滑
      while(h<=t && q[h]<j-(ti[i]-ti[i-1])*d) h++;
      while(h<=t && f[last][q[t]]<=f[last][j]) t--;
      q[++t]=j;
      f[now][j]=f[last][q[h]]+b[i]-abs(a[i]-j);
    }

    for(int j=n,h=1,t=0;j>=1;j--){ //第j位置 窗口左滑
      while(h<=t && q[h]>j+(ti[i]-ti[i-1])*d) h++;
      while(h<=t && f[last][q[t]]<=f[last][j]) t--;
      q[++t]=j;
      f[now][j]=max(f[now][j],f[last][q[h]]+b[i]-abs(a[i]-j));
    }
  }
  
  LL ans=-1e18;
  for(int i=1;i<=n;i++) ans=max(f[m&1][i],ans);
  cout<<ans;
}

 

posted @ 2023-04-29 14:16  董晓  阅读(360)  评论(0)    收藏  举报