![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
文章平均质量分 88
lianxuhanshu_
这个作者很懒,什么都没留下…
展开
-
leetcode 3098. 求出所有子序列的能量和【记忆化搜索】
首先将所有元素从小到大排序,任意元素之间的最小差值等价于所有相邻元素差值的最小值,然后我们需要从n个元素中选出刚好k个元素,求所有这样的子序列的能量值的和,对于所有的长为k的子序列我们可以采取记忆化搜索的方式来处理,mem[i][j][v]表示从第i个元素开始并且选择了j个元素并且选择的所有元素中相邻元素的最小差值为v的所有子序列的能量值之和,知道了状态定义然后直接记忆化搜索即可。中唯一一个长度为 2 的子序列是。由于答案可能会很大,将答案对。空间复杂度:O(n^3*k)。两个元素的差值绝对值的。原创 2024-04-01 12:32:30 · 503 阅读 · 0 评论 -
leetcode 2617. 网格图中最少访问的格子数【单调栈优化dp+二分】
需要经过的最少移动格子数,如果无法到达右下角格子,请你返回。时间复杂度:O(n*m*(log(n)+log(m)))。上图展示了到达右下角格子经过的 4 个格子。上图展示了到达右下角格子经过的 3 个格子。空间复杂度:O(n*m)。无法到达右下角格子。原创 2024-03-22 15:41:39 · 728 阅读 · 0 评论 -
Codeforces Round 926 (Div. 2) D. Sasha and a Walk in the City【树形dp】
最终答案就是f(1)+f(2)+...f(n)+1,那么最后为什么还要加1呢,这个加1的树中所有点都不染色的情况。在第一个测试用例中,有 2^3−1=7 个集合是可以选的,除了集合 {1,2,3} 以外,因为如果在城市中只有 {1,2,3} 中的路口是危险的,那么路口 1,2,3 对应的道路构成的简单路径 1−2−3 包含了 3 个危险路口。在第二个测试用例中,有 2^4−1=15 个集合是可以选的,但是其中 {1,2,3,4},{1,2,3},{1,3,4},{2,3,4} 不是合法的集合。原创 2024-03-21 12:37:16 · 1129 阅读 · 0 评论 -
Codeforces Round 927 (Div. 3) F. Feed Cats【差分+排序+dp】
其中lp[i]表示覆盖位置 i 的所有线段区间的左端点的最小值,如果没有区间覆盖 i ,那么lp[i]=i,cnt表示覆盖位置i的线段区间数,其中lp通过排序后可以使用双指针预处理好,cnt可以差分预处理。f(i,1)=max(f(lp[i]-1,0),f(lp[i]-1,1))+cnt,然后max(f(lp[i]-1,0),f(lp[i]-1,1))是等价于f(lp[i],0)的。定义f(i,1/0)表示是否投喂第i个位置能喂养的最多猫的个数,那么就有如下状态转移。时间复杂度:O(n+m)。原创 2024-03-18 11:23:03 · 348 阅读 · 0 评论 -
Codeforces Round 932 (Div. 2) C. Messenger in MAC【挖掘计算公式性质+排序+dp】
/选择当前位置,这里和MAX取min可以防止爆int,就可以不使用longlong了,因为如果f[i][j]超过MAX和置为MAX不影响结果,因为总代价l<MAX,所以超出l的部分是没有意义的。定义f[i][j]表示到了第i个位置并且选择了j个元素最小代价,a的代价就是所有ai的和,b的代价就是max(bi)-min(bi) (i属于s),s是我们选中的元素的集合。首先如果按照从小到大的顺序排列为[b1,b2,b3,...,bk],代价就是|b1-b2|+|b2-b3|+...+|b(k-1)-bk|原创 2024-03-17 18:23:38 · 1641 阅读 · 0 评论 -
leetcode 2312. 卖木头块【划分型dp+棋盘切割类型dp】
这个题目是一个经典的棋盘切割dp,严格来说其实也算一个划分类型dp,这个题目要注意的就是每次切割都是完全切割的,不存在那种切到一半再转方向的那种切割,如果不是完全切割切到一半可以转方向那种,我感觉这个题目就难多了,但是这个题目说了是完全切割,一刀直接切到底的那种,这样就简单多了,这个时候属于经典的棋盘切割dp,直接考虑dp即可。原创 2024-03-15 10:46:38 · 951 阅读 · 0 评论 -
leetcode 3077. K 个不相交子数组的最大能量值【划分型dp+式子等价变形】
唯一一种选 5 个不相交子数组的方案是:nums[0..0] ,nums[1..1] ,nums[2..2] ,nums[3..3] 和 nums[4..4]。等价转换为:f[i][j]=max(f[i][j-1],s[j]*w+f[i-1][L]-s[L]*w),i<=L<=n-k+i)f[i][i-1]=负无穷,划分i个子数组至少需要i个元素,i-1个元素无法划分出i个子数组,所以初始化为负无穷。f[i][j]表示前j个元素划分出i个子数组的最大能量值。f[0][j]=0,划分0个子数组能量值为0。原创 2024-03-11 11:40:44 · 836 阅读 · 0 评论 -
leetcode 3068. 最大节点价值之和【树形dp】
首先我们可以发现一个明显的性质就是每个结点位置的最终值和具体的操作次数没有关系,只和操作次数的奇偶性有关,当前位置i如果操作次数为奇数,那么当前位置值变为nums[i]^k,否则当前位置的值为nums[i],此时状态就把一个非常大的无限空间的状态就缩小为了一个有限的搜索空间,就可以考虑dp了,dp的关键就在于怎么设计状态,通过上面分析我们可以知道只和操作次数的奇偶性有关,我们设计状态只需要设计奇偶性即可。f[x][0]表示结点x操作偶数次时,子树x除去x的最大价值和。9 是可以得到最大的价值之和。原创 2024-03-07 12:02:17 · 1102 阅读 · 0 评论 -
leetcode 2581. 统计可能的树根数目【换根dp】
如上图所示,左边图最开始0号结点为根结点,右图所示为换根操作,把根换为1号点,我们可以发现换根之后相对于换根的前一步比较,只有换根的俩个点之间父子关系发生翻转,另外的其他所有点之间的父子关系不变,发现这个性质之后我们就可以根据换根造成的影响来计算这个新树中满足要求的猜测数量,然后判断这个数量是否大于等于k,从而更新答案。根为节点 3 ,正确的猜测为 [1,0], [2,1], [3,2], [3,4]根为节点 1 ,正确的猜测为 [1,3], [1,0], [2,4]Bob 的猜测用二维整数数组。原创 2024-02-29 11:20:58 · 1490 阅读 · 0 评论 -
牛客周赛 Round 32 F.小红的矩阵修改【三进制状态压缩dp】
时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 262144K,其他语言524288K。原创 2024-02-12 17:51:13 · 1342 阅读 · 0 评论 -
牛客周赛 Round 31 E.小红的子集取反【dp+设置偏移量】
时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 262144K,其他语言524288K。原创 2024-02-07 11:37:38 · 627 阅读 · 0 评论 -
牛客周赛 Round 30 F.小红叒战小紫【期望dp】
时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 262144K,其他语言524288K。原创 2024-01-31 11:21:05 · 985 阅读 · 0 评论 -
AtCoder Beginner Contest 338F - Negative Traveling Salesman【floyd+状态压缩dp】
时间复杂度:floyd预处理时间复杂度为O(n^3),n=20,这个时间大概是8e3,状态压缩dp处理时间复杂度为O((2^n)*n*n),这个时间大概为4e8,这个时间复杂度很高了,但是这个题目给了6s的时间,所以是可以过的,最终是时间复杂度为O((n^3)+(2^n)*n*n)。如果存在这样的行走,请找出所遍历的边的最小总权重。最终走过的点的集合肯定是(1原创 2024-01-30 19:30:19 · 1310 阅读 · 0 评论 -
leetcode514. 自由之路【线性dp】
时间复杂度:不妨设m=key.size(),n=ring.size(),第一维枚举步数,时间为O(m),第二维枚举key[i]在ring中出现的位置,时间为O(n),第三维枚举key[i-1]在ring中出现的位置,时间为O(n),最终时间复杂度为O(m*(n^2)).key[i]从key[i-1]转移过来,k枚举的就是key[i-1]在ring中出现的位置,用i-1步走到k来更新i步走到j。对于 key 的第一个字符 'g',已经在正确的位置, 我们只需要1步来拼写这个字符。,表示需要拼写的关键词。原创 2024-01-29 11:47:45 · 791 阅读 · 0 评论 -
AcWing 5460. 连续整数序列【哈希dp】
连续整数序列指的是由若干个连续正整数组成的递增序列,例如 [1],[3,4,5],[7,8,9,10,11] 都是合法的递增序列。给定一个长度为 n 的正整数序列 a1,a2,…,an,请你找到该序列的一个尽可能长的子序列,使得该子序列恰好是一个连续正整数序列。注意,子序列不一定连续。原创 2024-01-26 17:02:40 · 705 阅读 · 0 评论 -
牛客周赛 Round 29 F.小红又战小紫【概率dp】
时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 262144K,其他语言524288K。原创 2024-01-22 17:28:57 · 1097 阅读 · 0 评论 -
洛谷 P1622 释放囚犯【区间dp】
首先题目说了释放的人的所在牢房编号按递增的顺序给出,所以不需要在排序了,现在唯一影响吃肉数量的因素就是释放的顺序,先释放谁后释放谁的问题,对于一个区间[l,r],我们考虑最后一个释放的位置为k,那么释放k之后,就会形成俩个新的需要处理的区间f[l,k-1],f[k+1,r],这个不就是经典的区间dp了吗,然后我们考虑区间dp进行处理即可。现在正好牢房是满的。最后一步是处理k,a[r+1]-a[l-1]-1表示的是区间[l,r]数的个数,我们释放k,所以需要吃肉的数量为a[r+1]-a[l-1]-1-1。原创 2024-01-20 11:41:27 · 1044 阅读 · 0 评论 -
洛谷 P1541 [NOIP2010 提高组] 乌龟棋【线性dp+挖掘性质优化】
乌龟棋中 M 张爬行卡片,分成 4 种不同的类型(M 张卡片中不一定包含所有 4 种类型的卡片,见样例),每种类型的卡片上分别标有 1,2,3,4 四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。定义f[a][b][c][d]表示当前拥有1,2,3,4中类型的卡牌数为a,b,c,d,到达的位置就是1+a*1+b*2+c*3+d*4所能获得的最大得分。对于 50%50% 的数据有 1≤N≤120,1≤M≤50,且 4 种爬行卡片,每种卡片的张数不会超过 20。原创 2024-01-18 12:09:33 · 1137 阅读 · 1 评论 -
洛谷 P1537 弹珠【多重背包+二进制优化】
首先这里有6种弹珠,每种弹珠的价值为从1到6,每种弹珠有多个,我们需要将这些物品分为俩部分,使得俩部分的价值相同,也就是说现在有俩个人来分这些弹珠,每个人要分得一半价值的弹珠,假设所有弹珠的价值总和为sum,就转换为了要从其中选择若干弹珠,这些弹珠的价值总和为sum/2,看这种选法是否存在。如果所有的弹珠的价值相同,那么他们就可以平分。时间复杂度:多重背包二进制优化时间复杂度为O(n*v*log(s)),n=6,v=2e4,log(s)大概是14,所以时间大概为1e6,这个时间是肯定可以过的。原创 2024-01-17 11:31:54 · 1242 阅读 · 0 评论 -
洛谷 P1523 旅行商简化版【线性dp+npc问题简化版】
时间复杂度:第一维枚举后面那个人当前所在点,时间为O(n),第二维枚举前面那个人当前所在点,时间为O(n),最终时间复杂度为O(n^2),n=1000,最终时间就是1e6,这个时间复杂度是肯定可以过的。i走到j+1,j暂时不动,并且需要交换i,j位置,原本i变为j+1,j还是j,现在交换变为i变为j,j变为j+1,交换位置才能保证前面那个仍然在前面,后面那个也仍然在后面。定义f[i][j]表示后面那个人走到i这个点,前面那个人走到j这个点,并且i<j,并且1~j之间的所有点都走过一次了的最短距离。原创 2024-01-16 11:42:54 · 923 阅读 · 1 评论 -
AcWing 5386. 进水出水问题【线性dp+差值dp】
某泳池装有 n 个水管,编号 1∼n。每个水管都是既可用于进水,也可用于出水。其中,第 i 个水管工作时的单位时间进水或出水量为 ai。我们希望泳池保持水循环的同时,还能够保持水位不变。为此,我们需要制定一种水管工作方案。请你计算,一共可以制定出多少种不同的水管工作方案。注意,(1 号水管进水、2 号水管出水)和(1 号水管出水、2 号水管进水)应当视为两种不同的方案,虽然它们用到的工作水管相同,但是水管的具体安排(进水或出水)不同。原创 2024-01-14 21:42:50 · 959 阅读 · 1 评论 -
洛谷 P1489 猫狗大战【背包+bool类型dp】
从上述分析可以知道这俩部分必定有一部分兵的数量为n/2,我们令m=n/2,然后我们可以用sum来记录所有的n个兵的总的血量,我们只要知道其中一部分的血量blood,那么另一部分的血量就可以通过sum-blood算出来,所以我们只需要处理其中一部分的血量即可。枚举所有的f[n][m][k] (0<=k<=m*40),看从前n个物品中选择m个物品并且血量刚好为k的情况是否存在,如果存在,那么其中一部分血量为k,另外一部分的血量为sum-k,对所有存在的情况取一个最接近的值即可。原创 2024-01-13 11:55:00 · 965 阅读 · 1 评论 -
洛谷 P1442 铁球落地【线性dp+线段树预处理+离散化】
所以我们要么每次往左滚,要么就是往右滚,并且不管是往左边滚还是往右边滚都是只能掉到某一个确定的线段上的,也就是说可能的情况是有限的,这个观察题目描述中给出的图就可以发现了,这明显就是线性dp的常规操作,所以我们可以考虑进行dp,并且这个题目说了所有线段的l,r,h都是不同的,所以我们可以根据高度从小到达对所有线段进行排序,由于这个球从上面掉下来最终肯定会到达地面的某一个位置,我们可以把地面作为初始位置考虑从下往上进行dp。我们是以地面为初始状态,所以f[0][0]=f[0][1]=0。原创 2024-01-12 17:08:22 · 1501 阅读 · 1 评论 -
洛谷 P1439 【模板】最长公共子序列【线性dp+dp模型转换】
总结:这个题目属于诈骗题了,题目表面是求最长公共子序列,但是n非常大,n=1e5,显然最长公共子序列的那个O(n^2)解法过不了,观察状态转移方程也没有发现很明显的优化方式,但是我们画图之后发现了一个性质,就将原本的求最长公共子序列变为了求最长上升子序列,然后采用最长上升子序列二分+贪心写法这个题目就可以过了,这个题目纯属套着羊皮的狼,挂羊头卖狗肉,题目给的虽然是求最长公共子序列,但是本质上就是求最长上升子序列。,n 的两个排列 P1 和 P2 ,求它们的最长公共子序列。第一行是一个数 n。原创 2024-01-11 10:56:22 · 1235 阅读 · 0 评论 -
洛谷 P1433 吃奶酪【状态压缩dp】
时间复杂度非常高肯定过不了,那么我们看看能不能有某种优化方式呢,首先我们定义f[i]表示到达点i的所有路径的最小值,f[i]可以用来更新后面的若干个状态,也就是说爆搜的的情况下会有很多状态存在多次计算,也就是说存在一些重复的计算,这个时候就可以想到dp,因为dp就是用来优化掉一些重复计算的,然后我们可以发现n=15,n是非常小的,通过n非常小这个性质我们就可以知道这个题目八九不离十就是状态压缩dp了呀,下面考虑状态压缩dp的处理。对于两个点 (x1,y1),(x2,y2),两点之间的距离公式为。原创 2024-01-10 11:42:59 · 1186 阅读 · 1 评论 -
洛谷 P1430 序列取数 【区间dp+挖掘性质优化】
对于题目给定的操作是每次从左侧或者右侧取一段数,那么我们来看看有没有什么等价的操作,我们发现可以将一次取一段数改为一次取一个数,一次取可以进行多次操作,通过连续取这一段数的长度,也就取得了这一段数,所以这俩种操作实际上是可以等价转换的,然后我们考虑每次取一个数设计状态。由于最开始取时,可以取左边的数也可以取右边的数,所以答案就是max(f[1][n][0],f[1][n][1])也就是g[l][r]=(s[r]-s[l-1])-max(f[l][r][0],f[l][r][1]);我们可以定义如下状态。原创 2024-01-09 11:21:42 · 1016 阅读 · 0 评论 -
洛谷 P1417 烹调方案 【背包+推公式】
根据上述状态转移可以发现f[i][]只和f[i-1][]有关,所以实际上可以把空间压缩到一维,就是01背包压缩空间的那个写法,但是这个题目空间足够,不压缩也可以过,我这里就不压缩了,要压缩随便改一下就行了,二维写法好理解一点,我这里就写的二维的解法了。处理的过程中如果有空闲时间不处理食材,那么肯定会让收益变小,所以我们应该抓住所有时间处理,中间不能空闲时间,也就是说所有物品处理都是连续的,所以我们把状态定义为时间刚好为j更好处理状态转移。然后考虑因素2,食材选定之后,考虑处理食材的顺序让总收益最大。原创 2024-01-08 11:50:32 · 1062 阅读 · 0 评论