我写过的动态规划问题的状态表示与转移汇总

我写过的动态规划问题的状态表示与转移汇总

众所周知,在写 dp 问题时只要想出来状态表示和转移方程就能把一道题写的差不多了,所以在这里整理一下我写过的 dp 问题的解法,方便我后面举一反三。

我的其他动态规划文章:

背包动态规划

Luogu P1802 5 倍经验日 橙

题目来源:Luogu - 新手动态规划合集

题目链接,看了题解。

\(n\) 个体积为 \(use_i\) 的物品装容量为 \(m\) 的背包,一个物品最多装 \(1\) 次,如果装且能装下得到
\(win_i\) 价值,不装得到 \(lose_i\) 价值,求最大价值。

\(f_{i, j}\) 为装前 \(i\) 个物品,容量最大为 \(j\) 的最大价值,则有:

\[装得下:f_{i, j} = \max(f_{i-1, j-use_i}+win_i, f_{i-1, j}+lose_i) \]

\[装不下:f_{i, j} = f_{i-1, j} + lose_i \]

时间复杂度 \(O(nm (\max use_i))\).

死因:状态表示写成了:\(f_{i, j}\) 为装前 \(i\) 个物品,用了 \(j\) 体积的最大价值

P1832 A+B Problem(再升级) 橙

题目来源:Luogu - 新手动态规划合集

题目链接,看了题解。

给定一个正整数 \(n\),求将其分解成若干个素数之和的方案数。

判断出所有到 \(n\) 的素数,既然素数可以无限取那就是完全背包,所以本题是 线性筛 + 完全背包求方案数

\(f_j\) 表示从前 \(i\) 个物品(素数)里选,体积恰好为 \(j\) 的方案数,则有:

\[f_{j} = f_{j} + f_{j-v_i} \]

时间复杂度我不知道。

死因:猪脑子没想出来。

P1049 [NOIP 2001 普及组] 装箱问题 橙

题目链接

\(n\) 个体积为 \(v_i\) 的物品装进体积为 \(m\) 的背包,求最小剩余容量。

\(v_i\) 同时看作体积和价值即可,剩下就是 0-1 背包了。

P1060 [NOIP 2006 普及组] 开心的金明 橙

题目链接

有点无脑,不想写。

线性动态规划

Luogu P1359 租用游艇 橙

题目来源:Luogu - 新手动态规划合集

题目链接

\(n\) 个点,从点 \(i\) 到点 \(j\) 的代价为 \(r_{i, j}\) 且任意 \(i,j\) 之间都存在单向的 \(r_{i, j}\),求从点 \(1\) 到点 \(n\) 的最小代价。

\(f_i\) 为到点 \(i\) 的最小代价,则有:

\[f_i = \min_{j=1}^{j<=n-1}(f_{i-j}+r_{i,j}) \]

时间复杂度 \(O(n^2)\).

Luogu P1077 [NOIP 2012 普及组] 摆花 橙

题目来源:Luogu - 新手动态规划合集

题目链接

\(n\) 种物品,每个物品 \(s_i\) 个,同种物品放在一起,求选够 \(m\) 个物品的方案数。

\(f_{i, j}\) 为在前 \(i\) 种物品里选,总共选了 \(j\) 个,第 \(i\) 种物品选了 \(k\) 个的方案数,则有:

\[f_{i, j} = f_{i, j} + f_{i, j-k} \]

时间复杂度 \(O(nm\bar s)\).

区间与环形动态规划

P3146 [USACO16OPEN] 248 G 绿

题目链接,看了题解。

给定 \(1\) 个长度为 \(n\) 的正整数序列,每次可以选择两个相邻且相等的数 \(a_i\)\(a_j\) 合并为 \(a_i+1\),最大化序列最大值。

看到合并就想区间 dp,所以:

\(f_{l, r}\)\(a_{[l,r]}\) 中合并的最大值,\(l \le k < r\),则有:

\[f_{l, r} = max(f_{l, r}, f_{l, k}+1) \quad if:f_{l,k} = f_{k+1, r} \; \& \; f_{l, k} > 0 \]

时间复杂度:\(O(n^3)\).

P1063 [NOIP 2006 提高组] 能量项链 绿

题目链接,看了题解。

给你 \(n\) 个带权 \(a_i\) 点组成的一个环,每次操作可以合并相邻两个点\(a_i, a_j, i < j\),合并后的权值为 \(a_i\),对答案的贡献为 \(a_i \times a_j \times a_{j+1}\),最大化贡献。

\(f_{l, r}\)\(a_{[l, r]}\) 合并的最大价值,\(l \le k < r\),则有:

\[f_{l, r} = max(f_{l, r}, f_{l, k}+f_{k+1, r}+a_l\times a_k+1 \times a_r+1) \]

意思就是 \(f_{l,r}\) 等于左区间合并的贡献 加上 右区间合并的贡献 加上 合并两个区间的贡献,其中合并两个区间的贡献为左区间第一个珠子乘右区间第一个珠子乘右区间后面第一个珠子。

多练啊,时间复杂度 \(O(n^3)\).

树形动态规划

P1352 没有上司的舞会 黄

题目链接

给你一个带点权的树,要求选出一些点满足点权和最大且没有点相邻。

\(f_{u,0}\) 表示以 \(u\) 为根的子树的最大权值和且不选 \(u\)
\(f_{u,1}\) 表示以 \(u\) 为根的子树的最大权值和且选 \(u\),则有:

\[f_{u,0} \leftarrow f_{u,0} + max(f_{j,1}, f_{j, 0}) \]

\[f_{u,1} \leftarrow f_{u, 1} + f_{j, 0} \]

时间复杂度 \(O(n)\).

P2016 战略游戏 黄

题目链接

给你一棵树,一个点可以激活相邻的边,要求所有边被激活且选点最小。

\(f_{u, 0}\) 为以 \(u\) 为根的子树中最小的选点数且不选 \(u\)
\(f_{u, 1}\) 为以 \(u\) 为根的子树中最小的选点数且选 \(u\),则有:

\[f_{u, 0} \leftarrow f_{u, 0} + min(f_{j, 0}, f_{j, 1}) \]

\[f_{u, 1} \leftarrow f_{u, 1} + f_{j, 0} \]

时间复杂度 \(O(n)\).

P1122 最大子树和 黄

题目链接

给你一棵带可负点权树,一棵子树的点权为以它为根的子树所有点权之和,找出最大子树点权。

\(f_{u}\) 为以 \(u\) 为根的子树中最大的子树和,则有:

\[f_{u} = max(f_u, f_j+f_u) \]

时间复杂度 \(O(n)\).

状态压缩动态规划

数位动态规划

posted @ 2025-10-20 19:03  Misaka2298  阅读(6)  评论(0)    收藏  举报