![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
文章平均质量分 77
动态规划
cutlery1137
这个作者很懒,什么都没留下…
展开
-
第十届蓝桥杯国赛C/C++ B组第2题【01背包】
2019可以被分解成若干个两两不同的素数,请问不同的分解方案有多少种?注意:分解方案不考虑顺序,如2+2017=2019和2017+2=2019属于同一种方案。程序说明:分解成若干个,不是分解成两个,注意看题。f[i][j] 表示从前 i 个数中选,相加等于 j 的所有方案数。类似于01背包问题,只不过存的是方案数。如果j < prime[i],即加上第 i 个质数就会超出背包的容量,则f[i][j] = f[i - 1][j]如果j >= prime[i],即加上第 i 个质数不会原创 2020-11-07 17:26:42 · 381 阅读 · 3 评论 -
洛谷P1734 最大约数和【01背包】
题目链接:P1734 最大约数和代码如下:#include <iostream>using namespace std;const int N = 1010;int n, v[N], f[N][N], w[N];int main() { cin>>n; //预处理每个数的约数和 for(int i = 1; i <= n; i++) for(int j = 1; j < i; j++) if原创 2020-11-07 15:29:58 · 191 阅读 · 0 评论 -
leetcode 53. 最大子序和【贪心】【线性DP】
题目链接:53. 最大子序和给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?示例 1:输入: [2,2,1]输出: 1示例 2:输入: [4,1,2,1,2]输出: 4代码如下://贪心class Solution { public int maxSubArray(int[] nums) { int res = nums[0];原创 2020-05-30 11:20:22 · 199 阅读 · 0 评论 -
leetcode 198. 打家劫舍【线性DP】
题目链接:198. 打家劫舍你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。示例 1:输入: [1,2,3,1]输出: 4解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。原创 2020-05-29 14:01:54 · 172 阅读 · 0 评论 -
leetcode 121. 买卖股票的最佳时机【线性DP】
题目链接:121. 买卖股票的最佳时机给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。注意你不能在买入股票前卖出股票。示例 1:输入: [7,1,5,3,6,4]输出: 5解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润...原创 2020-03-10 12:14:25 · 177 阅读 · 0 评论 -
leetcode 322. 零钱兑换【背包问题】
题目链接:322. 零钱兑换给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。示例 1:输入: coins = [1, 2, 5], amount = 11输出: 3解释: 11 = 5 + 5 + 1示例 2:输入: coins = [2], amount = 3输出...原创 2020-03-08 18:27:43 · 165 阅读 · 0 评论 -
洛谷P1002 过河卒【DP】
题目链接:P1002 过河卒程序说明:不需要搜索,很容易就能求出转移方程。f[i][j]从两个方向即f[i - 1][j]和f[i][j - 1]转移过来,但是要注意边界情况,因为下标从0开始会有负数的情况,所以f整个平移一位,f[1][1]可以从f[1][0]转移过来。另外注意马所在的位置也需要被标记。结果很大要开long long。代码如下:#include <iostrea...原创 2020-03-03 16:21:22 · 177 阅读 · 0 评论 -
洛谷P1387 最大正方形【DP】
题目链接:P1387 最大正方形程序说明:参考了Ice_teapoy大佬的题解 第一个题解。f[i][j]表示a[i][j]左上角的最大正方形边长。f[i][j] 由 f[i - 1][j],f[i][j - 1],f[i - 1][j - 1] 三者的最小值转移过来。为什么是最小值?因为比最小值大的话就一定包含0了。三者取最小可以用两个min函数。代码如下:#include <i...原创 2020-02-27 21:39:13 · 181 阅读 · 0 评论 -
洛谷P1020 导弹拦截【LIS 贪心+二分】
题目链接:P1020 导弹拦截程序说明:第一个问题是求最长非上升子序列。upper_bound和lower_bound只能对非递减序列进行查找,由题可知 f 数组是单调递减的,因此需要在upper_bound函数中多一个参数:greater()或者手写cmp。第二个问题是求最长上升子序列(Dilworth定理),证明的方法可以参考大佬的博客:DP-导弹拦截。即最长上升子序列和最大非上升子序...原创 2020-02-26 21:31:43 · 287 阅读 · 0 评论 -
没有上司的舞会【树形DP】
题目链接:285. 没有上司的舞会Ural大学有N名职员,编号为1~N。他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。每个职员有一个快乐指数,用整数 Hi 给出,其中 1≤i≤N。现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。输入格式第一行一个整数...原创 2020-02-26 18:22:09 · 175 阅读 · 0 评论 -
洛谷P1091 合唱队形【线性DP】
题目链接:P1091 合唱队形程序说明:f[i]表示 i 左侧的最长上升子序列,g[i]表示 i 右侧的最长上升子序列。合唱队形的总人数为 f[i] + g[i] - 1。总人数减去合唱队形人数的最大值,就是出列的同学的最小值。代码如下:#include <iostream>using namespace std;const int N = 110;int a[N],...原创 2020-02-25 22:15:10 · 179 阅读 · 0 评论 -
最短Hamilton路径【状态压缩DP】
题目链接:91. 最短Hamilton路径 给定一张 n 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径。 Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次。输入格式第一行输入整数n接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(记为a[i,j])。对于任意的x,y,z,数据保证 a[x,x]...原创 2020-02-25 09:23:39 · 230 阅读 · 0 评论 -
蒙德里安的梦想【状态压缩DP】
题目链接:291. 蒙德里安的梦想 求把NM的棋盘分割成若干个12的的长方形,有多少种方案。例如当N=2,M=4时,共有5种方案。当N=2,M=3时,共有3种方案。如下图所示:(图在链接里.)输入格式输入包含多组测试用例。每组测试用例占一行,包含两个整数N和M。当输入用例N=0,M=0时,表示输入终止,且该用例无需处理。输出格式每个测试用例输出一个结果,每个结果占一行。数据范围...原创 2020-02-24 16:56:39 · 336 阅读 · 0 评论 -
整数划分【DP】
题目链接:900. 整数划分一个正整数n可以表示成若干个正整数之和,形如:n=n1+n2+…+nk,其中n1≥n2≥…≥nk,k≥1。我们将这样的一种表示称为正整数n的一种划分。现在给定一个正整数n,请你求出n共有多少种不同的划分方法。输入格式共一行,包含一个整数n。输出格式共一行,包含一个整数,表示总划分数量。由于答案可能很大,输出结果请对10910^9109+7取模。数据范...原创 2020-02-23 19:21:41 · 918 阅读 · 0 评论 -
洛谷P2758 编辑距离【线性DP】
题目链接:P2758 编辑距离程序说明:dp[i][j]表示前a的前 i 个字母和b的前 j 个字母匹配所需要的最少的操作次数,转移方程可以分为三种情况:删除:a的前 i - 1 个字母和b和前 j 个字母匹配,然后删掉a的第 i 个字母。即dp[i - 1][j] + 1。增添:a的前 i 个字母和b和前 j - 1 个字母匹配,然后把 b[j] 增添到 a[i] 的后面去。即dp[i...原创 2020-02-20 10:01:02 · 232 阅读 · 0 评论 -
洛谷P1880 [NOI1995]石子合并【区间DP】
题目链接:P1880 [NOI1995]石子合并程序说明:这道题和P1090 合并果子有些类似,但合并果子的过程是构造一棵哈夫曼树,而这道题是只能合并相邻的石子,通过模拟可以证明贪心得到的答案是错的,因此用动态规划来做。设dp[l][r]表示从 l 到 r 区间合并石子的代价的最小值,用k来划分区间,每次合并都终归于把 l 到 k - 1 和 k 到 r 两个子区间合并,然后加上区间的和(...原创 2020-02-19 12:30:17 · 252 阅读 · 1 评论 -
最长公共子序列【线性DP】
题目链接:897. 最长公共子序列 给定两个长度分别为N和M的字符串A和B,求既是A的子序列又是B的子序列的字符串长度最长是多少。输入格式第一行包含两个整数N和M。第二行包含一个长度为N的字符串,表示字符串A。第三行包含一个长度为M的字符串,表示字符串B。字符串均由小写字母构成。输出格式输出一个整数,表示最大长度。数据范围1≤N≤1000输入样例:4 5acbdabed...原创 2020-02-18 10:42:07 · 463 阅读 · 0 评论 -
洛谷P1115 最大子段和【线性DP】
题目链接:P1115 最大子段和程序说明:设dp[i]表示以第 i 个数结尾的最大字段和。根据递推式 dp[i] = max(a[i], dp[i - 1] + a[i]),说白了就是如果加上前一个数反而变小的话,就把前面的数都扔掉。注意边界问题,因为第一个数如果是负数的话,有可能dp的起始值会被更新成0。。因此一定要注意dp起始值的初始化,然后从第二个数开始遍历。代码如下:#incl...原创 2020-02-17 22:07:58 · 216 阅读 · 0 评论 -
洛谷P1049 装箱问题【01背包】
题目链接:P1049 装箱问题程序说明:令价值和体积相等就变成01背包问题了。代码如下:#include <iostream>using namespace std;const int N = 20010;int v[N], dp[N], n, m;int main() { cin>>m>>n; for(int i = 1; i <...原创 2020-02-17 18:07:44 · 231 阅读 · 0 评论 -
最长上升子序列【线性DP】【贪心+二分】
题目链接:896. 最长上升子序列 II给定一个长度为N的数列,求数值严格单调递增的子序列的长度最长是多少。输入格式第一行包含整数N。第二行包含N个整数,表示完整序列。输出格式输出一个整数,表示最大长度。数据范围1≤N≤100000−109≤数列中的数≤109输入样例:73 1 2 1 8 5 6输出样例:4程序说明:动态规划时间复杂度O(n2n^2n2)dp[...原创 2020-02-17 13:43:55 · 492 阅读 · 0 评论 -
数字三角形【线性DP】
题目链接:P1216 [IOI1994][USACO1.5]数字三角形 Number Triangles程序说明:第一种做法是从上往下递推,每个点可以从左上角或者右上角得到,思路简单但是注意边界问题,即考虑到最右侧的点也会从右上角得到,因此初始化时内层循环是1 ~ i + 1。最后遍历最后一层找到最大的数即为答案。第二种做法是从下往上递推,将每个数更新成左下方和右下方的数取较大者,再加上原...原创 2020-02-17 09:34:51 · 225 阅读 · 3 评论