【动态规划】
文章平均质量分 54
动态规划
不牌不改
※ 接受自己很普通
展开
-
L3-020 至多删三个字符 (30 分)
题目题目链接题解动态规划。状态表示:f[i][j]表示前i个字符删除j个后不同的字符串数。首先简单考虑一下,对于第i个字符,我们可以选择删除或者不删除,即f[i][j] = f[i-1][j-1] + f[i-1][j]看个例子cdabnaxy,删除abn和删除bna后得到的字符串都是cdaxy,说明存在多统计的情况,那么我们要减去这些重复的情况。根据上面那个例子可以发现对于一个字符s[i],如果在i之前存在一个x使得s[x]=s[i],那么删除[x,i-1]间的字符和删除[x+1,i]间的原创 2022-04-20 00:16:39 · 785 阅读 · 0 评论 -
蓝桥杯2019年第十届国赛真题-最优包含
题目题目链接题解动态规划。(有点像最长公共子序列)状态定义:dp[i][j]表示S前i个字符要想包含T前j个字符,需要经过的最少修改次数。转移方程:① S[i] == T[j]:此时无需进行变换,S前i个字符要想包含T前j个字符需要经过的最少修改次数就等于S前i-1个字符要想包含T前j-1个字符需要经过的最少修改次数,即dp[i][j] = dp[i-1][j-1]② S[i] != T[j]:两种情况转移而来。其一,为了让S前i个字符包含T前j个字符,我们只需要让让S前i-1个字符包含T原创 2022-04-06 20:42:44 · 619 阅读 · 0 评论 -
蓝桥杯2019年第十届省赛真题-糖果
题目题目链接题解数位DP。a[i]表示第i包糖果的状态;f[i]表示i这种状态所需的最少糖果包数。状态就是指一串二进制,最低位表示是否能吃到第1种糖果,次低位表示是否能吃过第2种糖果。转移方程:f[j | a[i]] = min (f[j | a[i]], f[j] + 1)含义是j | a[i]这种选了第i包糖果的状态所需的最少糖果包数为构成状态j的最少包数+1。s1 | a[i]表示没有拿第i糖果所能吃到的糖果的状态,与a[i]按位或实现将s2在a[i]中是1的位置上的数变为1,相当于原创 2022-04-05 22:42:25 · 535 阅读 · 0 评论 -
1040 有几个PAT (25 分)
题目题目链接题解动态规划。f[i][j]表示前i个字符中构成PAT中前j个字符构成字符串的个数,其实就是f[i][1]表示前i个字符构成P的个数,f[i][2]表示前i个字符构成PA的个数,f[i][3]表示前i个字符构成PAT的个数。状态转移,以更新f[i][2]为例子,如果s[i]==A,那么前i-1个字符构成P后加上这个A就可以得到PA,这样得到的PA个数为前i-1个字符构成P的个数,即f[i-1][P]=f[i-1][1],这些是新构成的,因为使用了新的字符s[i],还有之前就已经构成的原创 2022-03-28 20:04:59 · 487 阅读 · 0 评论 -
2021年蓝桥杯A组省赛-左children右sibling
CXXX有毛病?“左孩子右兄弟”字眼很敏感吗???题目题目链接题解贪心,DFS。以 uuu 为根的子树选择包含节点最多的以 vvv 为根的子树作为最后连接的右兄弟能保证树向下延展的最多。所以重点转换为了计算以 uuu 每个子结点为根的子树中包含节点最大的个数,递归计算每个子树的节点数(不含根节点),每棵子树能构成的最深深度为其直接子节点数量+能构造出来最深的二叉树的深度(并不是全部节点数量)一开始想的是每次都以最大的子树向下扩展,但是写代码的时候想成了以直接子结点最多的子树向下扩展。.原创 2022-03-27 10:02:25 · 1244 阅读 · 0 评论 -
2021年蓝桥杯A组省赛-回路计数
题目题解动态规划。最经典的哈密顿回路的题就是ACwing动态规划基础课的题和算法进阶指南中的了,都是用于讲解状压dp的。(但我还是没想到)f[i][j]f[i][j]f[i][j] 表示从起点(任意)走到 jjj ,经过的所有点用状态 iii 表示,所有的方案数。iii 被我们认为是个二进制数,每一位表示从起点到 jjj 是否经过对应的点。从最低位到最高位分别对应点 0∼n−10\sim n-10∼n−1,状态 iii 的第 kkk 位(从低到高,从 000 开始)二进制位为 111 表示状态原创 2022-03-26 21:58:41 · 2440 阅读 · 2 评论 -
2018年蓝桥杯C/C++B组国赛-激光样式
题目题目链接题解动态规划,或者找规律。找规律的话是斐波那契数列。动态规划的话也很简单,dp[i][0/1]表示前i个灯,第i个灯开或不开的方案数,转移方程为dp[i][0] = dp[i-1][0] + dp[i-1][1]、dp[i][1] = dp[i-1][0],最后输出dp[30][0] + dp[30][1]。代码#include<bits/stdc++.h>using namespace std;int dp[40][2]; // dp[i][0/1] 表示开原创 2022-03-16 18:42:04 · 655 阅读 · 0 评论 -
LeetCode338. 比特位计数
题目连接https://leetcode-cn.com/problems/counting-bits/解题思路这道题需要计算从 0 到 num 的每个数的二进制表示中的 1 的数目。最直观的方法是对每个数直接计算二进制表示中的 1 的数目,时间复杂度较高。也可以使用动态规划的方法,时间复杂度较低。为了表述简洁,下文用「一比特数」表示二进制表示中的 1 的数目。方法一:暴力暴力,时间复杂度O(n*sizeof(integer))注意,虽然是暴力,但是仍可以进行优化。按位与运算(&)的一原创 2021-03-03 21:49:01 · 148 阅读 · 0 评论 -
2017年蓝桥杯B组C/C++省赛-包子凑数
题目题目链接题解数论、动态规划。数论知识:如果 aaa 和 bbb 互质,则 x∗a+y∗bx*a+y*bx∗a+y∗b 无法得到的最小值为 a∗b−a−ba*b-a-ba∗b−a−b,又即 (a−1)∗(b−1)(a-1)*(b-1)(a−1)∗(b−1)。比如 222 和 333,不可以构成 111,可以构成 222,可以构成 333,可以构成 4=2+24=2+24=2+2,可以构成 5=2+35=2+35=2+3,……,之后的数都可以构成。111 是无法由 222 和 333 构成的最大原创 2022-03-15 10:19:36 · 483 阅读 · 0 评论 -
2018年蓝桥杯C++ B组省赛-测试次数
题目题目链接题解动态规划。dp[i][j]表示使用i部手机从j层高的塔验证采用最佳策略,在最坏的运气下测试的次数。状态转移:当只有一部手机时,最坏情况下我们需要从第 1 层一直测试到第 j 层楼,那么一共测试 j 次,dp[1][j] = j当拥有两部或两部以上手机时,这时我们需要考虑最优策略。当前我们在第 k 层测试,用到第 i 部手机时,测试会出现两种情况① 摔坏:如果在第 k 层摔坏了,那么我们只需要用剩下的 i - 1 部手机去测试剩下的 k - 1 层楼,即 dp[i原创 2022-03-13 18:37:53 · 901 阅读 · 0 评论 -
算法提高课-第一章-动态规划
友好城市原创 2022-03-12 17:23:20 · 732 阅读 · 0 评论 -
2995:登山
题目题目链接题解动态规划(最长上升子序列)。求一个先递增再递减的子序列的最大长度。一般思路:枚举中间单调性发生变化的位置,分别计算左侧的最长递增子序列长度和右侧最长递减子序列长度,记录二者之和的最大值。优化做法:预处理记录下每个位置对应的左侧的最长递增子序列长度和右侧最长递减子序列长度。枚举中间单调性发生变化的位置时只需要进行加法和比较运算即可,所以枚举的时间复杂度为O(n)O(n)O(n),最终算法的复杂度由O(n2)O(n^2)O(n2)的最长上升子序列算法决定。代码O(n^2)/原创 2022-03-12 17:13:50 · 506 阅读 · 0 评论 -
怪盗基德的滑翔翼
题目题目链接题解动态规划(最长上升子序列)。将题目抽象成考点很关键。本质上就是计算最长上升子序列和最长下降子序列中的较长者的长度。最长下降子序列可以通过将数组逆序、逆序遍历数组的方式或者更改判断条件等方式转化为最长上升子序列的计算。代码#include<bits/stdc++.h>using namespace std;const int N = 110;int f[N][2], a[N], T, n;int main(){ cin >> T;原创 2022-03-11 22:02:00 · 473 阅读 · 0 评论 -
最大上升子序列和
题目题目链接题解动态规划。dp[i]表示以第i个元素结尾的上升子序列的最大和,转移方程为dp[i] = max {a[i], dp[j] + a[i]},最后遍历全部的i找到最大的dp值。状态定义还是比较基础、比较常见的。我感觉这道题不要理解成最长上升子序列的变式,而是要理解成一道基础动态规划的变式,要求子序列上升完全可以看作方程转移需要满足的要求。代码#include<bits/stdc++.h>using namespace std;const int N = 1e原创 2022-03-11 20:10:14 · 432 阅读 · 0 评论 -
P2782 友好城市
题目题目链接题解最长上升子序列。存在加强数据,动态规划的最长上升子序列只能过基础数据,O(n2)O(n^2)O(n2)。加强数据需要使用贪心优化的O(nlogn)O(nlogn)O(nlogn)做法。难点有二:想到先排序;想到用最长上升子序列.这种题想到先排序应该是要靠题量累积起来的,一开始我是直接按照输入顺序(即无序)进行遍历,要求只要第i个桥的两端城市坐标比第j个桥两端的城市坐标都大,那么就可以由第j个城市转移而来。但是样例就错了,所以想到了先对一端的城市排序,先保证一端的城原创 2022-03-11 19:42:39 · 449 阅读 · 0 评论 -
最长上升子序列模板与优化后的模板
未优化#include<bits/stdc++.h>using namespace std;const int N = 1e5+10;int n, ans;int a[N], f[N];int main(){ cin >> n; for (int i = 1;i <= n;i ++) { cin >> a[i]; f[i] = 1; for (int j = 1;j < n;j ++) if (a[i] > a[原创 2022-03-11 19:34:39 · 185 阅读 · 0 评论 -
LeetCode300. 最长递增子序列
题目连接https://leetcode-cn.com/problems/longest-increasing-subsequence/解题思路方法一:动态规划思路与算法定义 dp[i] 为考虑前 i 个元素,以第 i 个数字结尾的最长上升子序列的长度,注意 nums[i] 必须被选取。我们从小到大计算 dp 数组的值,在计算 dp[i] 之前,我们已经计算出 dp[0…i−1] 的值,则状态转移方程为:dp[i]=max(dp[j])+1,其中0≤j<i且num[j]<num[i]原创 2021-03-04 21:40:32 · 135 阅读 · 0 评论 -
2017年蓝桥杯省赛-承压计算
题目题目链接题解动态规划。f[i][j]表示第i行第j列承受的重量(含第i行第j列物品的重量)转移方程:f[i][j] = f[i-1][j]/2 + f[i-1][j-1]/2,即左肩物品重量的一半+右肩物品重量的一半+自身重量,如果左肩或右肩没有物品,则相当于扛着重量为0的物品。最后根据比例算出最重称重显示多少即可。又是思考如何处理浮点数想了半天,最后发现只要改个double就行。代码 7原创 2022-03-11 12:58:04 · 211 阅读 · 0 评论 -
2021蓝桥杯模拟赛-跳跃
题目题目链接题解动态规划。算是比较基础的状态方程和状态定义,但是难点在于处理负权重的情况。代码#include<bits/stdc++.h>using namespace std;const int N = 1100;int f[N][N], w[N][N], n, m;int dir[2][9] = {-1, -2, -3, 0, -1, -2, 0, -1, 0, 0, 0, 0, -1, -1, -1, -2, -2, -3};int main(原创 2022-03-11 09:15:31 · 582 阅读 · 0 评论 -
蓝桥杯2021年第十二届真题-数字三角形
题目题目链接题解动态规划重点是如何分析“向左下走的次数与向右下走的次数相差不能超过 1”。这句话保证了从山顶走到山底,如果高度为奇数,则一定落在最中间的位置,如果高度为偶数,则一定落在中间的两个位置。即假设高度为NNN,每一行、列从索引0开始。如果NNN为奇数,则最后一定是到达(N−1,N/2)(N-1, N/2)(N−1,N/2);如果NNN为偶数,则最后一定是到达(N−1,N/2−1)(N-1, N/2-1)(N−1,N/2−1)或(N−1,N/2)(N-1, N/2)(N−1,N/2)。原创 2022-03-09 10:54:42 · 297 阅读 · 0 评论 -
蓝桥杯2015年第六届真题-生命之树
题目题目链接题解树状DP。基础树状DP题了。首先先讲一下题目什么意思(起初,我就理解错了)题目说在树上找一些点,这些点满足:在这些点中任取两个点a和b,都能够找到一条路径连通。我这样一翻译是不是感觉清晰多了,其实就是找一个点集,保证点击任意两点可达,这就是在找个连通区域。(最开始,我理解成了要找一条直径使得直径上的点价值加起来最大……)dp[i][0/1]表示以i为根的子树不选取根节点i和选取根节点i构成连通区域的最大分数;(比较难以描述)dp[i][0]是不选根节点,意味着以i为根原创 2022-03-08 22:37:20 · 161 阅读 · 0 评论 -
蓝桥杯2021年第十二届真题第一场-砝码称重
题目题目链接题解动态规划。状态定义:dp[i][j]表示前i个砝码是否能称出重量为j的物品。状态转移:对于第i个砝码,选和不选两种情况;对于选又可以分为放在左边和放在右边。看样例,存在加和减的情况,也就是放在左边和右边的情况。我们规定放在左边用加表示,放在右边用减表示。那么第i个砝码的全部情况为第i个砝码不放、放左边或放右边。对于重量为j的物品,如果不放第i个砝码,则dp[i][j] |= dp[i-1][j],即若用i-1个砝码可以称出j,那么用i个砝码肯定也行;如果将第i个砝码放在左边(原创 2022-03-08 13:01:51 · 594 阅读 · 0 评论 -
蓝桥杯2021年第十二届真题第二场-整数分解
题目【问题描述】将 3 分解成两个正整数的和,有两种分解方法,分别是 3 = 1 + 2 和3 = 2 + 1。注意顺序不同算不同的方法。将 5 分解成三个正整数的和,有 6 种分解方法,它们是 1+1+3 = 1+2+2 =1 + 3 + 1 = 2 + 1 + 2 = 2 + 2 + 1 = 3 + 1 + 1。请问,将 2021 分解成五个正整数的和,有多少种分解方法?【答案提交】这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的原创 2022-03-07 11:37:34 · 812 阅读 · 0 评论 -
蓝桥杯2021年第十二届真题第二场-国际象棋
题目题目描述众所周知,“八皇后” 问题是求解在国际象棋棋盘上摆放 888 个皇后,使得两两之间互不攻击的方案数。已经学习了很多算法的小蓝觉得 “八皇后” 问题太简单了,意犹未尽。作为一个国际象棋迷,他想研究在 N×MN × MN×M 的棋盘上,摆放 KKK 个马,使得两两之间互不攻击有多少种摆放方案。由于方案数可能很大,只需计算答案除以 100000000710000000071000000007 (即 109+710^9+7109+7) 的余数。如下图所示,国际象棋中的马摆放在棋盘的方格内,转载 2022-03-07 19:11:19 · 461 阅读 · 0 评论 -
P1020 [NOIP1999 普及组] 导弹拦截
导弹拦截详解 动态规划 lower_bound upper_bound Dilworth定理 最长上升子序列 最长不上升子序列 详细 总结 详解原创 2022-01-18 12:14:52 · 830 阅读 · 0 评论 -
P1018 [NOIP2000 提高组] 乘积最大
高精度 动态规划 DP 乘积最大 提高组原创 2022-01-17 14:59:24 · 1539 阅读 · 1 评论 -
P1006 [NOIP2008 提高组] 传纸条
传纸条 洛谷 DP 动态规划原创 2022-01-14 10:16:21 · 434 阅读 · 0 评论 -
没有上司的舞会
题目题目链接题解树形dp。状态定义比较固定。f[i][0]表示以i为根的子树中,不选i时的最大值或最小值,f[i][1]表示以i为根的子树中,选i时的最大值或最小值。状态转移一般需要根据题目判断,只要用子节点的f信息合理更新f[i][0]和f[i][1]即可。主要提及邻接表。代码#include<bits/stdc++.h>using namespace std;const int N = 6005;int n, idx, e[N << 1], ne[N &原创 2022-01-13 12:01:14 · 135 阅读 · 0 评论 -
最短Hamilton路径
最短Hamilton路径 状压dp 动态规划原创 2022-01-13 10:22:00 · 252 阅读 · 0 评论 -
蒙德里安的梦想
蒙德里安的梦想原创 2022-01-12 12:17:33 · 327 阅读 · 0 评论 -
蓝桥杯2017年第八届真题-对局匹配
题目题目链接题解动态规划。题目大意:在一个具有nnn个元素的集合中选取尽可能多的数,保证这些数不存在两个数相差为kkk,求个数。(题目讲的乱七八糟)首先,我们统计每个数的个数,c[i]表示有多少个i;对于每个数,都可以选或者不选,若我们不选数i−ki-ki−k,则我们可以选数iii,也可以不选数iii;但若我们选数i−ki-ki−k,则我们绝不能选数iii了。还有一种很奇怪的情况,当数iii的个数为0时,我们根本就无法选这个数,因此我们完全可以选数i−ki-ki−k或者不选数i−ki-k原创 2021-08-21 23:10:42 · 566 阅读 · 0 评论 -
蓝桥杯算法训练VIP-邮票
题目题目链接题解动态规划。整体思路:dp[i]表示构成价值为i至少需要多少张;从1开始从小到大遍历全部价值,若中途存在一种价值无法在使用不超过n张的前提下构成,则说明从此断开,输出这个数-1即可。每一个大价值都是由小价值构成,转移方程为:dp[i] = min(dp[i], dp[i-j] + dp[j]),j=1~i-1;既然能遍历到价值i说明价值1~i-1都是可以在使用不超过n张的前提下构成。想要构成价值i,就遍历之前的全部价值,看看最小需要多少张,赋值给dp[i]。代码#incl原创 2021-08-16 15:08:25 · 149 阅读 · 0 评论 -
蓝桥杯算法训练VIP-方格取数
题目题目链接题解动态规划。本题和这个题几乎是完全一样,那个博客写的巨清楚,所以这里不写了。代码#include<bits/stdc++.h>using namespace std;const int N = 20;int dp[N][N][N][N], n, x, y, v, a[N][N];int max(int a, int b, int c, int d) { return max(max(a, b), max(c, d));}int main(){原创 2021-08-13 21:19:04 · 225 阅读 · 0 评论 -
蓝桥杯算法训练VIP-拦截导弹
题目题目链接题解Dilworth定理 + 动态规划。第一问求最长不上升子序列长度;第二问求最长上升子序列长度。Dilworth定理断言:对于任意有限偏序集,其最大反链中元素的数目必等于最小链划分中链的数目。链:偏序集的子集,满足其中任意两个元素(不相同)可比。反链:偏序集的子集,满足其中任意两个元素(不相同)不可比。偏序集的链划分使用的最少集合数,等于它的最大反链长度。偏序集的反链划分使用的最少集合数,等于它的最大链长度。Dilworth定理证明即求不上升子序列的最小划分,相当于原创 2021-08-13 17:44:44 · 231 阅读 · 0 评论 -
蓝桥杯算法训练VIP-传纸条
题目题目链接题解动态规划。两个人一个人从左上角向右下角走,另一个人从右下角向左上角走,不允许路径上从同一个位置。我们完全可以转化为两个人都从左上角走,路径上不允许走同一个位置,两个人同时走到右下角的最大值。四维dp,dp[i][j][p][q]表示第一个人从左上角走到(i, j),同时第二个人也从左上角走到了(p, q)的最大值,这个最大值就是两条路径之和的最大值。一般转移方程:dp[i][j][p][q] = max(dp[i-1][j][p-1][q], dp[i-1][j][p][q-1原创 2021-08-12 13:10:25 · 320 阅读 · 0 评论 -
蓝桥杯算法训练VIP-乘积最大
题目题目链接题解动态规划。整体思路:dp[i][j]表示用i个乘号,对前j个数进行操作能得到的最大值;(看完dp数组如何定义后,可以尝试自己实现)num[i][j]表示第i个数到第j个数构成的十进制数的值;转移方程:dp[i][j] = max(dp[i][j], dp[i-1][k-1]*num[k][j]),其中k是在枚举乘号的位置,k = i+1 ~ j初始条件:dp[0][i] = num[1][i], dp[1][1] = 1思考过程(以下单纯是为了记录自己的思考过程,读者自原创 2021-08-11 00:20:50 · 193 阅读 · 1 评论 -
蓝桥杯算法提高VIP-邮票面值设计
题目题目链接题解DFS+动态规划。整体思路:第i个邮票的面值的范围为:value[i] = value[i-1]+1 ~ mx[i-1]+1,其中value[i]表示第i个邮票的面值,mx[i]表示前i个邮票能构成的连续最大数;解释一下这个范围,第i个邮票的面值至少比第i-1个邮票的面值多1,且必须要不超过前i-1个邮票(默认都是最多n张)所能构成的最大面值+1,要是大于最大面值+1就无法满足连续了。因此,如果我们知道前一个邮票的面值,那么我们就可以推出当前邮票的面值范围,枚举范围内的面值,进原创 2021-08-10 11:07:19 · 422 阅读 · 0 评论 -
蓝桥杯算法提高VIP-贪吃的大嘴
题目题目链接题解动态规划。多重背包模板题。转化成要放满承重为m的背包,所需的物品的最小价值为多少;每个物品的价值就是1,即1个,每种物品还有数量限制,套用多重背包模板即可。代码1是二维实现,代码2是一维实现。代码1#include<bits/stdc++.h>using namespace std;const int N = 110, M = 2e4+10;int dp[N][M], v, c;int n, m;int main(){ cin>>m原创 2021-08-09 15:23:04 · 295 阅读 · 0 评论 -
[蓝桥杯][算法提高VIP]促销购物
题目题目链接题解动态规划。看到底下的标签是动态规划之后,仔细一想确实可以转换为完全背包问题,但是背包开几维啊,每一维的容量可以表示为所需物品的最大件数,但是物品有999种啊。这时,我们的突破口就应该放在最多购买5种不同的商品上,这样我们只需要五维就可以控制选的五种商品了。与经典背包不同这个是求最小值,因此初始化非常关键。开始用的dfs实现的,无论怎么优化只能过89,剩下的超时,不知道原因。代码#include<bits/stdc++.h>using namespace s原创 2021-08-06 12:26:00 · 363 阅读 · 0 评论 -
蓝桥杯算法提高VIP-数的划分
题目题目链接题解动态规划。dp[i][j]表示用1~i这些数构造出j这个数的方案数;转移方程:含义为:对于每一个数i我们都可以选k次,要想构成j,则由前i-1个数构成j-k*i。边界为:dp[i][0] = 1,构成0的方案数为1,即都不选。其实由上面的式子可以简化一层循环,转移方程为:dp[i][j] = dp[i-1][j] + (j>=i?dp[i][j-i]:0)当j>=i时,dp[i][j] = dp[i-1][j] + dp[i][j-i],否则,dp[i][原创 2021-08-08 19:05:33 · 189 阅读 · 0 评论