
动态规划
文章平均质量分 52
筱竹&XZ
这个作者很懒,什么都没留下…
展开
-
[USACO3.2] 香甜的黄油 Sweet Butter(Dijkstra)
给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)。这道题实际上就是要求出所有有牛的牧场的到每个牧场的最短路。第 N+2 行到第 N+C+1 行,每行包含三个整数 A,B,D,表示牧场号为 A 和 B 的两个牧场之间有一条长度为 D 的双向道路相连。然后剩下的工作就是枚举每个牧场然后把每一头奶牛到这个牧场的最短路径长度加起来求个和,比较所有的和的最小值。第二行到第 N+1 行,每行一个整数,其中第 i 行的整数表示第 i−1 头奶牛所在的牧场号。原创 2024-09-02 16:30:00 · 847 阅读 · 0 评论 -
NYOJ 1204 计蒜客-T1551-魔法少女 简单DP
在黑长直(小炎)往上爬楼去对抗魔女之夜时,她遇到了一个问题想请你帮忙。因为魔女之夜是悬浮在半空的,所以她必须要爬楼,而那座废墟一共有 nn 层,而且每层高度不同,这造成小炎爬每层的时间也不同。不过当然,小炎会时间魔法,可以瞬间飞过一层或者两层[即不耗时]。消灭魔女之夜是刻不容缓的,所以小炎想找你帮她找出一种最短时间方案能通往楼顶。接下去 N 行,每行一个数字 H(1≤H≤100),代表本层的高度。第一行一个数字 N(1≤N≤10000),代表楼层数量。输出一行,一个数字 S,代表通往楼顶所需的最短时间。原创 2024-09-02 09:45:00 · 346 阅读 · 0 评论 -
洛谷 P3183 [HAOI2016]食物链(记忆化搜索/拓扑排序)
物种的名称从 1 到 n 编号, M 条能量流动关系形如 a1→b1,a2→b2,a3→b3⋯am−1→bm−1,am→bm 其中 ai→bi 表示能量从物种 ai 流向物种 bi ,注意单独的一种孤立生物不算一条食物链。如果有若干条边 u1→v,u2→v,⋯uk→v ,那么只有当 f[u1],f[u2],⋯,f[uk] 全部计算完成时,才可以计算 f[v]。也即, DAG 中的有向边规定了计算的顺序,只有当一个点的所有前驱点都计算完成时,该点才可以计算。原创 2024-09-01 15:30:00 · 475 阅读 · 0 评论 -
P1048 [NOIP2005 普及组] 采药
辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药(共 m 株),采每一株都需要一些时间,每一株也有它自身的价值。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。我们用 f[i][j] 表示在 i,i+1,⋯,n−1,n 中选择物品,剩余时间为 j 时能选出的最大价值和。采药的时间 T(1≤T≤1000) ,一共有不超过 100 个草药,每个草药的价值和消耗的时间不超100。我们可以看出这是一道。原创 2024-09-01 09:00:00 · 632 阅读 · 0 评论 -
石子合并-环(区间dp)c++
所以我们只需要正常做区间 DP ,最后求dp[1][N],dp[2][N+1],…,dp[N][2×N−1] 的最小值即可。但如果做 N 次区间 DP 时间复杂度就变成了 O(n4),并且我们可以发现在其中有一些状态是重复计算的。刚才的《石子合并》问题是把石子放成一排,如果石子放成一个环,第 N 堆和第 1 堆相邻,又该怎么做呢?这 N 种放成一排的情况都考虑清楚,取其中的最优解,就一定是放成环的样子的最优解。我们要想办法把它变成之前放成一排的问题,可以发现只要我们把。原创 2024-08-31 12:46:00 · 383 阅读 · 0 评论 -
拓扑排序(c++)
观察上图可以发现,有一条 1→2 的有向边,表示 2 进入队列之前需要先让 1 进入队列。拓扑排序就是依照这个原理进行的,但是拓扑排序将这个判断过程简化为了对入度的判断。通过只判断入度,可以在保证正确性的情况下简化算法流程。通过上面的判断方式,我们发现可以根据一个点的入边来判断这个点进入队列前需要哪些点已经进入队列。这一名词,实际上拓扑序的定义与题目要求的排队序列定义相同,就是指满足该图要求的一种序列。所以,拓扑排序不仅可以用于求解拓扑序,也可以用于判断一个有向图中是否存在有向环。原创 2024-08-30 14:19:50 · 708 阅读 · 0 评论 -
洛谷P1040 NOIP2003提高组---加分二叉树
设一个 n 个节点的二叉树 tree 的中序遍历为 (1,2,3,⋯,n),其中数字 1,2,3,⋯,n 为节点编号。试求一棵符合中序遍历为 (1,2,3,⋯,n)且加分最高的二叉树 tree。subtree 的左子树的加分 × subtree 的右子树的加分 + subtree 的根的分数。第 1 行:一个整数,为最高加分(结果不会超过 4,000,000,000)。第 2 行:n 个用空格隔开的整数,为每个节点的分数(分数 <100)。第 2 行:n 个用空格隔开的整数,为该树的前序遍历。原创 2024-08-29 14:17:35 · 588 阅读 · 0 评论 -
奇怪的花卉(树形DP——最大子树和)
一株奇怪的花卉,上面共连有 N 朵花,共有 N−1 条枝干将花儿连在一起,并且未修剪时每朵花都不是孤立的。每朵花都有一个“美丽指数”,该数越大说明这朵花越漂亮,也有“美丽指数”为负数的,说明这朵花看着都让人不舒服。所谓“修剪”,意为:去掉其中的一条枝条,这样一株花就成了两株,扔掉其中一株。老师的任务就是:通过一系列“修剪”(也可以什么“修剪”都不进行),使剩下的那株(那朵)花卉上所有花朵的“美丽指数”之和最大。老师想了一会儿,给出了正解。一个数,表示一系列“修剪”之后所能得到的“美丽指数”之和的最大值。原创 2024-08-28 21:23:52 · 581 阅读 · 0 评论 -
等和的分隔子集
晓萌希望将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 · 372 阅读 · 1 评论 -
可行性判定(c++)
已知第 i 件物品的体积是 ci,每种物品有且仅有一件,每一件物品能够选择放或者不放入背包。普通的 01 背包中要求放入物品的体积之和不超过 V,而现在我们需要使体积之和恰好为 V。现在我们不考虑物品的价值,只关心是否能够取出若干个物品,恰好使这个背包被装满。因为结果只需要输出 V 这个体积是否能被组出,因此我们可以将 dp 数组定义成。也就是说,现在我们需要选出若干件物品,使它们的体积之和。时间复杂度为 O(NV),空间复杂度为 O(NV)。当前有 N 件物品和一个容积为 V 的背包。原创 2024-05-11 19:58:13 · 603 阅读 · 1 评论 -
完全背包问题(c++)
虽然物品个数是无限的,但是实际上,由于背包容量有上限,每个物品最多选取的个数也是有限制的,这样可以转换成多重背包问题,进而可以转换成 01 背包问题。现有容量为 V 的背包,请你放入若干物品,使总体积不超过 V,并且总价值尽可能大。当前有 N 种物品,第 i 种物品的体积是 ci,价值是 wi。每种物品的数量都是无限的,可以选择任意数量放入背包。可以用多重背包的思想来解决完全背包。原创 2024-05-09 20:11:20 · 796 阅读 · 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 · 677 阅读 · 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 · 492 阅读 · 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 · 550 阅读 · 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 · 595 阅读 · 0 评论 -
最大子段和
给定一个由数字组成的序列,其中连续的一段子序列称为一个 子段,子段中的所有数之和称为 子段和,这里只考虑非空子段,即至少包含一个元素的子段。这节课我们来学习如何求得一个序列中子段和最大的子段的子段和,即求 最大子段和。原创 2024-04-29 18:26:30 · 323 阅读 · 0 评论 -
最长上升子序列(c++)
最长上升子序列,就是给定序列的一个最长的、数值从低到高排列的子序列,最长上升子序列不一定是唯一的。先来确定状态,可以设 dp[i] 表示只考虑了前 i 个数的时候的最优解,考虑到达这个状态的最后决策,应该是把 a[i] 接到前边的一个子序列之后,那接下来就考虑怎么接。此时,我们在把 a[i] 接进前边的子序列的时候,就看 i 前边的每一位 j ,如果有 j原创 2024-05-03 14:52:51 · 635 阅读 · 0 评论