P1725 琪露诺[线性dp (优先队列/单调队列优化)]

📅 发布时间:2026/7/7 12:24:59 👁️ 浏览次数:
P1725 琪露诺[线性dp (优先队列/单调队列优化)]
P1725 琪露诺时间限制: 1.00s 内存限制: 125.00MB复制 Markdown中文退出 IDE 模式题目描述在幻想乡琪露诺是以笨蛋闻名的冰之妖精。某一天琪露诺又在玩速冻青蛙就是用冰把青蛙瞬间冻起来。但是这只青蛙比以往的要聪明许多在琪露诺来之前就已经跑到了河的对岸。于是琪露诺决定到河岸去追青蛙。小河可以看作一列格子依次编号为 0 到 N琪露诺只能从编号小的格子移动到编号大的格子。而且琪露诺按照一种特殊的方式进行移动当她在格子 i 时她只移动到区间 [iL,iR] 中的任意一格。你问为什么她这么移动这还不简单因为她是笨蛋啊。每一个格子都有一个冰冻指数 Ai​编号为 0 的格子冰冻指数为 0。当琪露诺停留在那一格时就可以得到那一格的冰冻指数 Ai​。琪露诺希望能够在到达对岸时获取最大的冰冻指数这样她才能狠狠地教训那只青蛙。但是由于她实在是太笨了所以她决定拜托你帮它决定怎样前进。开始时琪露诺在编号 0 的格子上只要她下一步的位置编号大于 N 就算到达对岸。输入格式第一行三个正整数 N,L,R。第二行共 N1 个整数第 i 个数表示编号为 i−1 的格子的冰冻指数 Ai−1​。输出格式一个整数表示最大冰冻指数。输入输出样例输入 #1复制运行5 2 3 0 12 3 11 7 -2输出 #1复制运行11说明/提示对于 60% 的数据N≤104。对于 100% 的数据N≤2×105−103≤Ai​≤1031≤L≤R≤N。数据保证最终答案不超过 231−1。朴素算法很好想 只要遍历每个位置i 然后取[i-r,i-l]区间的最大值 然后加上i位置的值即可 但是数据比较大 时间复杂度过不了 可以用堆维护这个区间的最大值 然后懒删除掉不在这个区间的值 这个删除可以用存储下标实现 或者用滑动窗口维护这个区间的最大值 效果更优化 堆优化更好些一点代码如下#include bits/stdc.h using namespace std; const int N2e55; int a[N]; int f[N]; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n,l,r; cinnlr; for(int i0;in;i){ cina[i]; f[i]INT_MIN; } f[0]0; priority_queuepairint,intq; for(int il;in;i){ if(ilf[i-l]!INT_MIN){ q.push({f[i-l],i-l}); } while(q.size()q.top().secondi-r){ q.pop(); } if(q.size()){ f[i]q.top().firsta[i]; } } int ansINT_MIN; for(int in-r1;in;i){ ansmax(ans,f[i]); } coutans\n; return 0; }