dp深入与进阶(1):线性dp+区间dp(2025.01.24)
01.线性dp(多维状态定义)
Luogu P1136 [迎接仪式]
根据题面考虑不交换
设置状态
前
个字符进行 次字符 的取反,
次字符 的取反,
取 或 : 指当前位为 , 指当前位为
为该条件下的最大价值 初始状态:
,利用性质: + 不满足条件)
讨论:
暴力
02.区间dp
i.Luogu P1063[能量项链]:
原题求一条长度为
可以将两条长度为
如此便将环的问题转化为了链上的区间dp问题
考虑定义
对于
有区间
方程 初始状态定义为
最后用for循环枚举k,区间dp即可
核心代码:
for(int len=1;len<n;++len)//枚举区间[i,j]的长度 for(int i=1,j=i+len;i+len<=2*n;++i,++j)//枚举起始点i和区间结尾j for(int k=i;k<j;++k)//枚举中转点 f[i][j]=max(f[i][k]+f[k+1][j]+head[i]*tail[k]*tail[j],f[i][j]);//区间dp:能合并就尝试合并 for(int i=1;i<=n;++i) ans=max(ans,f[i][i+n-1]);
ii.Luogu P1005 [矩阵取数游戏]:
考虑定义
考虑对于剩余区间
01.上一步取
02.上一步取
暴力枚举
核心代码:
for(int i=1;i<=n;++i) for(int l=1;l<=m;++l) for(int r=m;r>=l;--r)//枚举区间[l,r] f[i][l][r]=max(f[i][l-1][r]+1ll*a[i][l-1]*(1<<(m-(r-l+1)))/*要么是在选走l-1后变为[l,r]的区间*/,f[i][l][r+1]+1ll*a[i][r+1]*(1<<(m-(r-l+1)))/*要么是在选走r+1后变为[l,r]的区间*/); for(int i=1;i<=n;++i) { for(int l=1;l<=m;++l) maxn=max(f[i][l][l]+(1ll<<m)*a[i][l],maxn); ans+=maxn; }
本文作者:SamXia
本文链接:https://www.cnblogs.com/SamXia/p/18691759
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
,
,
,
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步