E48 单调队列优化DP Watching Fireworks is Fun
视频链接:456 单调队列优化DP Watching Fireworks is Fun_哔哩哔哩_bilibili
CF372C Watching Fireworks is Fun
时间:O(nm)
#include <iostream> #include <cstring> #include <algorithm> #define LL long long using namespace std; 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; int h=1,t=0; for(int j=1;j<=n;j++){ //第j位置 窗口右滑 while(h<=t && f[last][q[t]]<=f[last][j]) --t; q[++t]=j; if(q[h]<j-(ti[i]-ti[i-1])*d) ++h; f[now][j]=f[last][q[h]]+b[i]-abs(a[i]-j); } h=1,t=0; for(int j=n;j>=1;j--){ //第j位置 窗口左滑 while(h<=t && f[last][q[t]]<=f[last][j]) --t; q[++t]=j; if(q[h]>j+(ti[i]-ti[i-1])*d) ++h; 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; }
#include <iostream> #include <cstring> #include <algorithm> #define LL long long using namespace std; 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; int h=1,t=0; for(int j=1;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); } h=1,t=0; for(int j=n;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; }