DP
文章平均质量分 66
小胡同的诗
千里之行,始于足下
展开
-
LeetCode 96 不同的二叉搜索树(动态规划 | 递推 | Catalan数)
题目链接:leetcode96题面题目大意求 n 个数字构成的二叉搜索树的种类数量解题思路与本题等价的题目有:凸多边形划分三角形的数量、一串数字通过栈构成的出栈序列数量、2n 长度的 01 串的种类(限制是前缀 1 的数量不少于 0 )等,最终其实可以归结于 Catalan 数的计数问题。以下主要介绍两种动态规划思想的递推,为了方便讲解,问题不妨假设转化为数字的进栈出栈问题:递推我们考虑,对于一串规模为 n 的数字,对于状态 f[i]f[i]f[i] 表示把第 iii 个数字为开头的出栈原创 2020-09-20 10:13:46 · 193 阅读 · 0 评论 -
蓝桥杯--2015第六届C/C++B组省赛
相比较14年的难度下降,不过搜索的题目更多,多了一个树形DP(待补)奖券数目有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利。虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求。某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带“4”的号码,主办单位请你计算一下,如果任何两张奖券不重号,最多可发出奖券多少张。请提交该数字(一个整数),不要...原创 2019-03-02 19:08:57 · 337 阅读 · 0 评论 -
最长回文子串(二维DP)
题目链接:LeetCode5思路:除了马拉车算法和中心扩散法外的一种通用高效的算法,核心思路是优化暴力中查子串是否为回文串的二维DPclass Solution {public: string longestPalindrome(string str) { int len = str.size(); bool dp[1005][1005]; //dp...原创 2019-08-29 22:41:00 · 155 阅读 · 0 评论 -
7.8 DAG上的多源最短(长)路径问题(动态规划)
目录前言图模型算法DAG最短路描述实现DAG最长路描述实现DAG所有顶点对之间的最短路描述实现抽象图模型二维矩形嵌套分析思路1(转为DAG上最长路)思路2(转为LIS问题)硬币问题思路完全背包比较记忆化搜索递推打印路径补充n维矩形嵌套问题总结前言首先要知道什么是DAG,有向无环图,可以求拓扑排序,关键路径,在工程规划上有很大的用处。如果发现某个问题给的前提是DAG,那么,根据DAG的无圈性,...原创 2019-09-04 13:56:17 · 1457 阅读 · 0 评论 -
LeetCode32最长有效括号(DP+栈)
题目链接:Leetcode32思路:动态规划,复杂度O(n)O(n)O(n)注意状态要设计成以i位置为结尾的最长合法长度而不能只单单设计前i个字符的最长合法串,否则转移方程很难得到,状态转移时注意前不要越界,特别是第三个caseclass Solution {public: int longestValidParentheses(string s) { //...原创 2019-09-04 23:14:27 · 111 阅读 · 0 评论 -
LeetCode198打家劫社(线性动态规划)
题目链接:Leetcode198Code:class Solution {public: int rob(vector<int>& nums) { //dp[i]表示偷盗到第i家获得的最大收益 if (nums.size() == 0) return 0; if (nums.size() == 1) return ...原创 2019-09-04 23:47:55 · 184 阅读 · 0 评论 -
LeetCode746. 使用最小花费爬楼梯(线性动态规划)
题目链接:Leetcode746Code:class Solution {public: int minCostClimbingStairs(vector<int>& cost) { //dp[i]表示跳到第i层的花费 vector<int> dp(cost.size()+1, 0); dp[0] = ...原创 2019-09-05 00:00:21 · 132 阅读 · 0 评论 -
LeetCode121. 买卖股票的最佳时机(单调栈+动态规划)
题目链接:Leetcode121思路:1,找前面和它比最小的更新答案,可以维护一个单调栈解决,每次跟栈底比(实际上是单调队列,但不用控制窗口大小就是了)class Solution {public: int maxProfit(vector<int>& prices) { int n = prices.size(); if ...原创 2019-09-05 17:00:18 · 1029 阅读 · 0 评论 -
LeetCode338. 比特位计数(二进制+动态规划)
题目链接:Leetcode338思路:利用x&x-1很容易从前一个少1的数递推过来,复杂度O(n∗c)O(n*c)O(n∗c)class Solution {public: vector<int> countBits(int num) { //利用x&x-1快速计算比该数位小1的数然后递推 vector<int...原创 2019-09-10 00:02:11 · 157 阅读 · 0 评论 -
最少插入回文串(LCS+思维)
题目链接:51Nod思路:处理回文的东西许多时候要考虑反转一下与原串相比。对于本题,发现一个结论:原串与逆序串的LCS扣除后剩下的串长度恰好是我们要构造对称的最少长度,因为这样找LCS相当于回文串中找后面的一个匹配,当然LCS是不连续的,而回文要求连续,这样扣除一下恰好会是一个连续的结果。#include <bits/stdc++.h>using namespace std;...原创 2019-08-29 19:36:55 · 274 阅读 · 0 评论 -
最小编辑距离(二维DP)
题目链接:Leetcode72思路:状态dp[i][j] :表示s1的前i个字符以及s2的j个字符的编辑距离,这个字符在哪我们不关心(无后效性),为了递推的顺利,我们可以把字符串从前往后对应排放好,如果发现某个位置不相等那就在这个位置打个*,因为这个位置必然要添加上去初始条件 : dp[i][0]表示s1有i个字符而s2有0个字符,显然编辑距离为i;同理dp[0][i]=i状态转移方程...原创 2019-08-29 18:54:02 · 181 阅读 · 0 评论 -
树上最近公共祖先(欧拉序+RMQ)
算法描述根据上一个博客介绍的dfs序以及欧拉序能够把树上的点转为线性的区间点,从而可以用区间的数据结构去维护。根据欧拉序的定义,我们会发现树上任意两点的第一次出现位置之间必然夹带着lca的点,至于为什么可以画图理解一下,因为我们生成这个欧拉序时每次回溯就加一个点,而任意两点之间的搜索树一定是从lca开始往下搜,然后回溯再转而去搜另外一个点,所以lca就生成再两点的时间戳之间了。于是我们维护完欧...原创 2019-08-21 09:05:59 · 423 阅读 · 0 评论 -
剑指offer--剪绳子(贪心 | DP)
解题思路:有动态规划和贪心两种方法。贪心通过打表我们发现这样的规律:一个数拆分达到最大一定是其拆乘3的个数达到最大,但如果结尾剩下1的话要少拆1个3从而拼成1个4。动态规划dp[i]:表示将长度为i的线段裁剪为m段的乘积最大值 (2 <= m <= n)转移方程:dp[i] = dp[j] * dp[i-j] (1 <= j <= i/2)class So...原创 2019-03-09 22:39:52 · 358 阅读 · 0 评论 -
蓝桥杯--2017第八届C/C++B组省赛
搜索仍是重点,不过没上一届那么多了。基础的模运算和细节处理标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦,但又不好推辞。 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠的。 小明也有个怪癖,不到万不得已,从不刷卡,直接现金搞定。 现在小明很心烦,请你帮他计算一下,...原创 2019-03-10 20:22:13 · 250 阅读 · 0 评论 -
LCS的优化算法
链接:LCS转LIS(nlogn算法)PS智商被压制啊,没太懂,打个标记。将第一个序列离散化成位置数组这开始没看懂,除了二分还可以用树状数组,qwq。50分代码是滚动数组优化的LCS。...原创 2019-03-15 17:21:32 · 994 阅读 · 0 评论 -
PAT -- 甲级1007(1007 Maximum Subsequence Sum)
1007 Maximum Subsequence Sum (25 分)Given a sequence of KKK integers { N1N_1N1, N2N_2N2, ..., NKN_KNK }. A continuous subsequence is defined to be { NiN_iNi, Ni+1N_{i+1}Ni+1, ..., NjN_j...原创 2019-04-15 10:56:16 · 149 阅读 · 0 评论 -
FZU2214 Knapsack problem(DP 超大型01背包 + 滚动数组优化)
题目大意:给T组测试用例,每组一个n表示n件物品以及B表示背包容量,接下来n行表示物品体积以及价值,问该背包能够装下的最大价值为多少?思路:很容易考虑到01背包,不过背包的体积有1e9,很显然无法用常规的01背包写法,发现总价值最多只有5000,于是状态dp【i】可以设置成i价值下的体积最小值。于是状态转移方程就可以写成 dp【i + 1】【j】 = min(dp【i】【j】,dp【i】【j -...原创 2019-04-18 20:39:13 · 221 阅读 · 0 评论 -
台阶问题(动态规划)
链接:变态跳台阶题目详情:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。分析:状态:dp[n]:表示n级台阶跳法转移方程:dp[n] = dp[n-1]+dp[n-2]+…+dp[1]+1这里有两种推法:1,由于dp[n-1]=dp[n-2]+…+dp[1]+1所以dp[n] = dp[n-1] + dp[n-1...原创 2019-07-29 14:52:27 · 713 阅读 · 0 评论 -
矩形覆盖(动态规划)
链接:矩形覆盖题目详情:我们可以用2∗12*12∗1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2∗12*12∗1的小矩形无重叠地覆盖一个2∗n2*n2∗n的大矩形,总共有多少种方法?分析:看这样一个图,假如第列的那排用竖的填充,标为1,那么显然剩下的n-1列的排列方案数量就是它这样排的方案数;如果第n列第一行用横的填充,那么下一行和前一列这四块格子中明显都要标记为0,于是这...原创 2019-07-30 00:03:52 · 956 阅读 · 0 评论 -
RMQ问题(ST表)
算法描述ST表是根据倍增的思想设计的基于动态规划的做法,优点是能O(1)O(1)O(1)地查询,缺点是不能像线段树那样支持修改。关于预处理:枚举2的k次幂的区间长度,然后枚举起点将区间一分为2去求最大值关于查询:让两个子区间头和尾重叠分别接在待查区间的头和尾,然后尽可能的让区间长度j在n内大,做法是log2nlog2^nlog2n向下取整,显然最极限情况是两个子区间头尾相接没有重叠,其...原创 2019-08-19 16:10:49 · 175 阅读 · 0 评论 -
LeetCode877. 石子游戏(博弈+动态规划)
题目链接:Leetcode877思路:dp[i][j]表示从下标i到j中去左边和取右边的最大值转移方程:dp[i][j]=max(dp[i+1][j]+val[i], dp[i][j-1]+val[j]);显然,根据这个状态的设定有dp[i][i]=val[i];除此之外,i<=j记忆化搜索:class Solution {public: bool stoneGa...原创 2019-09-10 23:05:34 · 239 阅读 · 0 评论 -
LeetCode91解码方法(动态规划)
LeetCode91思路:dp[i]表示前i个数字能合法地转成字母,字母的种类数class Solution {public: int numDecodings(string s) { //dp[i]表示前i个数字能合法地转成字母,字母的种类数 int n = s.size(); vector<int> dp(n + 1,...原创 2019-09-12 22:11:31 · 1494 阅读 · 0 评论 -
LeetCode343. 整数拆分(动态规划)
Leetcode343思路:状态很好表示:dp[i]dp[i]dp[i]表示和为i的拆分数字积的最大值。关键在于前一个状态是拆了j数字,如果继续往下拆则是dp[i−j]∗jdp[i-j]*jdp[i−j]∗j,如果只拆成两部分就是j∗(i−j)j*(i-j)j∗(i−j)class Solution {public: int integerBreak(int n) { ...原创 2019-09-13 23:42:38 · 254 阅读 · 0 评论 -
LeetCode312戳气球(区间动态规划)
题目链接:思路:区间DP,枚举的点就是最后戳破的那颗汽球,然后左右区间递归,可以化成迭代的形式三层for。注意根据题目的要求要做第一个和最后一个的预处理,复杂度:O(n3)O(n^3)O(n3)。由于那个cost不满足四边形不等式的要求(不单调),所以不能优化下一个nclass Solution {public: int maxCoins(vector<int>&...原创 2019-09-24 23:04:36 · 330 阅读 · 0 评论 -
LeetCode152乘积最大子序列(动态规划)
题目链接:leetcode152思路:注意这里的子序列是子数组的意思!!dp[i]dp[i]dp[i]表示以下标i为结尾的最值,由于乘法的缘故,只要乘以一个数均可能成为后面最大值的贡献子段,所以要存一个最大乘积和最小乘积,意在把之前的绝对值最大的乘积子段存下来,以后当遇到一个负数就可以考虑由那个绝对值最大的状态传递过来。注意每个段可能由于之前是0,另起一段,所以也要考虑这个状态的计算。故维护最...原创 2019-09-26 00:03:07 · 197 阅读 · 0 评论 -
算法实验题8.1 半数集问题(记忆化搜索)
题目描述问题描述:给定一个自然数n,由n 开始可以依次产生半数集set(n)中的数如下。(1) n∈set(n);(2) 在n 的左边加上一个自然数,但该自然数不能超过最近添加的数的一半;(3) 按此规则进行处理,直到不能再添加自然数为止。例如,set(6)={6,16,26,126,36,136}。半数集set(6)中有6 个元素。注意半数集是多重集。实验任务:对于给定的自然...原创 2019-09-26 18:34:08 · 437 阅读 · 0 评论 -
LeetCode416分割等和子集(动态规划 or 搜索)
题目链接:leetcode416思路:动态规划背包问题,sum的一半的背包应尽可能地大,由于最优子问题地缘故,它会往sum/2的方向靠,于是跑一下背包最后判断一下这个位置是否能够平分sum。复杂度O(n∗sum)O(n*sum)O(n∗sum)class Solution {public: bool canPartition(vector<int>&...原创 2019-09-27 00:48:37 · 188 阅读 · 0 评论 -
LeetCode787K站中转内最便宜的航班(动态规划)
题目链接:leetcode787思路:首先这题可以bfs做,因为第一个约束是K中转站内,即搜K+1层然后松弛dist数组,当终点的dist没有被松弛过说明不通。根据这个思路可以设计一个二维状态dp[i][j]dp[i][j]dp[i][j]表示到达j点最多经过i个中转站的最少费用,于是状态转移方程可以推导为: dp[i][to]=min(dp[i][to], dp[i-1][from]+w[...原创 2019-09-28 12:44:13 · 492 阅读 · 0 评论 -
LeetCode898子数组按位异或操作(单调型动态规划)
题目链接:leetcode898dp[i]表示以A[i]为结尾的序列的区间或的不同个数,它肯定能够由之前的状态或上A[i]值会改变的所有状态传递过来也就是说,之前的状态需要去重,可以用上一个集合去重,最好输出集合的个数即dp要求的最终状态注意这个状态一定是连续的!!优化,由于或的特性,之后的状态与前面的状态不同一定是产生了更大的数才需要更新否则不更新通过单调性优化的思路目前自己还想不...原创 2019-09-30 08:12:39 · 438 阅读 · 0 评论 -
LeetCode231打家劫社Ⅱ(动态规划)
题目链接:leetcode213思路:在之前的基础上加上环的约束,可以特判第一个选与不选,最后把两个方向的最终状态取个最大返回。class Solution {public: int rob(vector<int>& nums) { int n=nums.size(); if(n==0) return 0; if(...原创 2019-09-30 08:54:44 · 121 阅读 · 0 评论 -
LeetCode337打家劫社Ⅲ(树形动态规划)
题目链接:leetdcode337思路:先序列化,再树形DP,上一个节点如果选取则下一层节点不会取,否则从下层选和不选选一个最大的传递上来。/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; ...原创 2019-09-30 13:26:58 · 268 阅读 · 0 评论 -
算法实验题4.4 逆序表问题(DP or 二分 or 线段树)
题目描述思路这个问题大致就是给你1~n数字对应的逆序数分别存到b[n]中,然后让你还原出原序列动态规划我们虽然不知道原序列长啥样,但我们知道它每个元素长啥样。并且最大那个数无论放到哪逆序数都是为0,于是先把这个数加到结果集中。问题就变成倒2个数根据逆序数考虑排倒结果集的位置,不难发现一个数字k他的逆序数s应满足0<=s<=n−k0<=s<=n-k0<...原创 2019-09-24 22:57:05 · 294 阅读 · 0 评论 -
LeetCode264丑数Ⅱ(动态规划 or 堆)
题目链接:leetcode264思路:堆每次把当前最小的丑数能递推到的丑数push进小根堆中,根据小根堆的性质每次pop一定是当前最小的丑数,复杂度O(nlogn)O(nlogn)O(nlogn)动态规划所有丑数的全集一定由2,3,5的倍数组成的集合以及1构成由于要按顺序输出丑数,即丑数集合要具有单调性枚举每个数字的倍数,显然一个数字的倍数集合单调递增维护三个指针每...原创 2019-09-23 10:09:50 · 312 阅读 · 0 评论 -
LeetCode309最佳买卖股票时机含冷冻期(动态规划)
题目链接:leetcode309思路:因为本题中规定买入,卖出和冷冻操作,规定上一次卖出和下一次买入之间需要至少一天的冷冻期,因此我们定义三种状态sell、buy和cooldown,分别对应了到第i天为止最后一个操作是买入、卖出和冷冻所对应的最大利润,则状态转移方程如下:sell[i]=max(sell[i-1],buy[i-1]+prices[i]);buy[i]=max(buy[i...原创 2019-09-16 12:12:46 · 256 阅读 · 0 评论 -
LeetCode413等差数列划分(动态规划)
题目链接:leetcode413思路:动态规划,dp[i]dp[i]dp[i]表示以i位置的数为结尾中形成等差数列的个数的集合。则每次如果以A[i]、A[i−1]、A[i−2]A[i]、A[i-1]、A[i-2]A[i]、A[i−1]、A[i−2]形成一个等差数列,则这个A[i]有可能由和之前i-1位置为结尾形成的所有等差数列分别拼接而成,所以计算集合的值时要加上dp[i−1]dp[i - 1...原创 2019-09-17 00:18:47 · 301 阅读 · 0 评论 -
LeetCode790多米诺和托米诺平铺(铺砖型动态规划)
题目链接:leetcode790思路:铺砖型动态规划,设dp[i][j]dp[i][j]dp[i][j]表示填满i列后还剩j块方砖,接着集合计算就可以和3∗n3*n3∗n的单种矩形填充的一样了,注意的是由于有L型方块,所以转移的地方要乘2,因为L型的两种排布方式恰能构成两种,其余都是依赖于上一个状态唯一确定的当前状态,所以不需要乘上倍数。其中,dp[i-2][0]转移到dp[i][0]虽然有两...原创 2019-09-18 17:03:08 · 504 阅读 · 0 评论 -
LeetCode638大礼包(7进制状压+完全背包 or DFS+剪枝)
题目链接:leetcode638思路:状态压缩+完全背包(状压DP)由于物品的种类不超过6种,实际上是6维的DP问题,可以用一个十进制数来存一个最大6位的7进制数种,之后就跟完全背包一样把每个礼包看成一个物品,而总的背包容量状态为tot,一个物品能放进背包当且仅当每个维度的物品数量都不超过背包容量。预处理和状态计算的复杂度:O(6+106∗77∗(6∗2))O(6+106*7^7*(6*...原创 2019-09-20 00:05:33 · 370 阅读 · 0 评论 -
LeetCode646最长对数链(贪心 or 动态规划)
题目链接:leetcode646思路:动态规划这题的动态规划和LIS的思想很接近,dp[i]dp[i]dp[i]表示前i个数对的最长链长度,但LIS由于是一维的可以用二分优化查找,而本题不行。为了消除后效性,本题还有预先做一个按右边界排序的预处理,其思想和DAG上的DP很像,DAG通过拓扑排序消除后效性,拓扑排序也是DAG的DP顺序。但本题用排序是由于还要建图,复杂度并没有降低,所以...原创 2019-09-20 18:11:26 · 298 阅读 · 0 评论 -
LeetCode740删除与获得点数(动态规划)
题目链接:leetcode740思路:根据题目给的数据范围,可以进行DP,dp[i]dp[i]dp[i]表示删除从1~i中存在的数中删除i这个数后的最大收益,显然数组中有几个i就能获得i∗ki*ki∗k的收益。于是可以利用计数排序。状态转移方程:dp[i]=max(dp[i−1],dp[i−2]+i∗k)dp[i]=max(dp[i-1],dp[i-2]+i*k)dp[i]=max(dp[...原创 2019-09-21 09:58:57 · 294 阅读 · 0 评论 -
应用举例2.9 Josephus排列问题
问题描述:思路:用循环链表模拟用数组游标模拟动态规划(数学方法)设dp[i]dp[i]dp[i]表示剩余i个人进行出环的最终胜利者,显然可以得到一个状态转移方程:dp[n]=(dp[n−1]+m)dp[n]=(dp[n-1]+m)%ndp[n]=(dp[n−1]+m)。相当于从1个人去推出n个人的递推关系。复杂度O(n)O(n)O(n)当n较大时有优化方法博文戳这里...原创 2019-09-22 08:36:18 · 245 阅读 · 0 评论