dadadadadka

dadadadadka
这是一个动态规划问题。灵梦从第一行出发每秒钟必须下移一行同时可以左右移动至多T格。目标是收集尽可能多的P点价值。解题思路状态定义定义 f[i][j] 表示到达第 i 行第 j 列时能获得的最大P点价值总和。状态转移从第 i-1 行到第 i 行灵梦可以左右移动至多 T 格所以textf[i][j] val[i][j] max(f[i-1][k])其中 |j - k| ≤ T即从上一行的 [j-T, jT] 范围内取最大值加上当前格子的价值。优化如果直接枚举 k时间复杂度为 O(N * M * T)会超时。使用单调队列优化对于每一行用单调队列维护窗口 [j-T, jT] 内的最大值将转移优化到 O(1)。完整代码#includecstdio#includectype.h#includecstring#defineintlonglong#definemax(a,b)ab?a:bconstintMARX4e310;intn,m,k,t,now,ans;intf[MARX][MARX];inthead,tail;intq[MARX];inlineintread(){intfl1,w0;charchgetchar();while(!isdigit(ch)ch!-)chgetchar();if(ch-)fl-1;while(isdigit(ch)){ww*10ch-0;chgetchar();}returnfl*w;}voidin(intx){while(tailheadf[now-1][x]f[now-1][q[tail]])tail--;q[tail]x;}intfind(intx){if(xtm)in(xt);while(q[head]tx)head;returnq[head];}signedmain(){nread(),mread(),kread(),tread();while(k--){intxread(),yread(),wread();f[x][y]w;}for(now2;nown;now){head1,tail0;for(inti1;itim;i)in(i);for(intj1;jm;j){f[now][j]f[now-1][find(j)];}}ans0;for(inti1;im;i){if(f[n][i]ans)ansf[n][i];}printf(%lld,ans);return0;