单调队列优化DP

单调队列优化dp

单调队列可以求某固定区间的最值,所以dp中需要求某固定区间的最值则可以考虑使用单调队列优化

单调队列-滑动窗口

https://www.luogu.com.cn/problem/P1886

P2034选择数字

https://www.luogu.com.cn/problem/P2034

solution:

f[i][1/0]表示考虑前i个数且第i个数选或不选

f[i][0]=max(f[i-1][0],f[i-1][1]) 第i个不选则看前i-1个选或不选的最大值

考虑f[i][1] 如果第i个数要选 因为最多选连续k个所以第i个数前面能选的数最多连续k-1个
注意到a[i]是非负整数 所以能选就选 则如果i前面的j不被选 则后面j+1到i-1的位置都可以选

i-k,i-k+1,i-k+2,.... i-2,i-1,i
⬆ .... ..... ..... ⬆

f[i][1]=max(f[j][0]+a[i]+a[i-1]+...a[j+1]) 后面a[i]+a[i-1]+....a[j+1]可用前缀和快速求出 所以
f[i][1]=max(f[j][0]+s[i]-s[j])=max(f[j][0]-s[j])+s[i]; (i-k<=j<=i-1)

如果暴力求出max(f[j][0]-s[j])则时间复杂度是O(n^2) 观察到每次j的范围长度都是(i-1)-(i-k)+1=k 是固定的
求固定长度的最值可以用滑动窗口 所以O(1) 即可求出max(f[j][0]-s[j])

Acwing 1089. 烽火传递

n个数连续k个里面只用选1个
https://www.acwing.com/problem/content/1091/

solution:

dp[i]表示前i个且选第i个的最小值
dp[i]=min(dp[j])+a[i];

i-m,i-m+1,i-m+2,....i-2,i-1,i;
如果i选了 则至少i-m得选

LC2944

https://leetcode.cn/problems/minimum-number-of-coins-for-fruits/description/

solution:

dp[i]表示前i个水果都被选中且i是花钱买的的最小金币数
dp[i]=min(dp[j])+w[i] (i/2<=j<i)

Acwing 4418. 选元素

https://www.acwing.com/problem/content/description/4421/

solution:

f[i][j]表示在前i个数中选j个数且第i个数被选上的最大和
因为第j个数在第i个位置被选中 而长度为k的连续子序列都至少包含一个被选中的元素
所以第j-1个数应该在[i-k,i-1]的位置被选择

f[i][j]=max(f[i][j],f[t][j-1]+w[i]) (i-k<=t<i)

posted @   Danc1ng  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示