动态规划
lunch( ̄︶ ̄)
这个作者很懒,什么都没留下…
展开
-
等和的分隔子集
晓萌希望将1到 N 的连续整数组成的集合划分成两个子集合,且保证每个集合的数字和是相等。例如,对于 N =3,对应的集合{1,2,3} 能被划分成{3} 和{1,2} 两个子集合。输出包括一行,仅一个整数,晓萌可以划分对应 N 的集合的方案的个数。当没法划分时,输出 0。对于 N =3,我们只有一种划分方法,而对于 N =7时,我们将有 4种划分的方案,输入包括一行,仅一个整数,表示 N 的值(1 ≤ N < 39)。这两个子集合中元素分别的和是相等的。原创 2024-05-13 18:32:28 · 332 阅读 · 1 评论 -
可行性判定(c++)
已知第 i 件物品的体积是 ci,每种物品有且仅有一件,每一件物品能够选择放或者不放入背包。普通的 01 背包中要求放入物品的体积之和不超过 V,而现在我们需要使体积之和恰好为 V。现在我们不考虑物品的价值,只关心是否能够取出若干个物品,恰好使这个背包被装满。因为结果只需要输出 V 这个体积是否能被组出,因此我们可以将 dp 数组定义成。也就是说,现在我们需要选出若干件物品,使它们的体积之和。时间复杂度为 O(NV),空间复杂度为 O(NV)。当前有 N 件物品和一个容积为 V 的背包。原创 2024-05-11 19:58:13 · 555 阅读 · 1 评论 -
完全背包问题(c++)
虽然物品个数是无限的,但是实际上,由于背包容量有上限,每个物品最多选取的个数也是有限制的,这样可以转换成多重背包问题,进而可以转换成 01 背包问题。现有容量为 V 的背包,请你放入若干物品,使总体积不超过 V,并且总价值尽可能大。当前有 N 种物品,第 i 种物品的体积是 ci,价值是 wi。每种物品的数量都是无限的,可以选择任意数量放入背包。可以用多重背包的思想来解决完全背包。原创 2024-05-09 20:11:20 · 603 阅读 · 1 评论 -
多重背包(c++)
这一份代码和 01 背包相比,不再有 else 部分了,因为,k = 0 的时候 dp[i][j] = max(dp[i - 1][j], dp[i][j]) ,相当于 01 背包的 else 部分。我们也可以在转移的过程中枚举 k,代表第 i 个物品选取的数量,和 01 背包的思想一样,有如下转移。我们可以把每个种类的 ni 个物品,都当成 01 背包里的不同种物品,只是恰巧体积和价值相同。与 01 背包不同的是,多重背包每种物品都有若干个,数量为 ni,是有限的。原创 2024-05-08 18:23:30 · 525 阅读 · 1 评论 -
01 背包问题(c++)
对于每个物品是否要装入背包,我们自然可以进行暴力枚举或搜索,但是如果要暴力地去做,那么时间复杂度会非常的高,这时候需要一种更优的算法——动态规划。为了使价值最大化,如果第 i 个物品放入背包后,总体积不超过限制且总价值比之前要大,那么就将第 i 个物品放入背包。当 ci≤j≤V 时, dp[i][j]=max(dp[i−1][j],dp[i−1][j−ci]+wi)前 i 个物品,放在背包里,体积之和不超过 j 的前提下,所获得的最大价值为 dp[i][j]。对于 01 背包,先确定这个问题的状态。原创 2024-05-07 21:59:07 · 434 阅读 · 0 评论 -
最长公共子序列(c++)
有了前面的基础,可以发现这个问题仍然可以按照序列的长度来划分状态,也就是 S1 的前 i 个字符和 S2 的前 j 个字符的最长公共子序列长度,记为 dp[i][j]。如果 S1 的第 i 项,和 S2 的第 j 项相同,那么 S1[i] 与 S2[j] 作为公共子序列的末尾,则。举一个例子,两个序列 S1=abcfbc 和 S2=abfcab,根据转移方程可以得出 dp[i][j]最长公共子序列:给定两个序列 S1 和 S2,求二者公共子序列 S3 的最长的长度。原创 2024-05-04 13:29:47 · 515 阅读 · 1 评论 -
[NOIP 2008] 传球游戏(c++)
比如有 33 个同学 11 号、22 号、33 号,并假设小蛮为 11 号,球传了 33 次回到小蛮手里的方式有 1→2→3→11→2→3→1 和 1→3→2→11→3→2→1,共 22 种。游戏规则是这样的:n 个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止,此时,拿着球没传出去的那个同学就是败者,要给大家表演一个节目。100%100% 的数据满足:3≤n≤30,1≤m≤30。原创 2024-05-03 15:04:34 · 444 阅读 · 0 评论 -
最大子段和
给定一个由数字组成的序列,其中连续的一段子序列称为一个 子段,子段中的所有数之和称为 子段和,这里只考虑非空子段,即至少包含一个元素的子段。这节课我们来学习如何求得一个序列中子段和最大的子段的子段和,即求 最大子段和。原创 2024-04-29 18:26:30 · 290 阅读 · 0 评论 -
最长上升子序列(c++)
最长上升子序列,就是给定序列的一个最长的、数值从低到高排列的子序列,最长上升子序列不一定是唯一的。先来确定状态,可以设 dp[i] 表示只考虑了前 i 个数的时候的最优解,考虑到达这个状态的最后决策,应该是把 a[i] 接到前边的一个子序列之后,那接下来就考虑怎么接。此时,我们在把 a[i] 接进前边的子序列的时候,就看 i 前边的每一位 j ,如果有 j原创 2024-05-03 14:52:51 · 322 阅读 · 0 评论