DP
文章平均质量分 64
AKone123456
这个作者很懒,什么都没留下…
展开
-
B. Catching Cheaters-----------------------思维(dp)
题意:给定a,b两个串,求最大的S(c,d) = 4 * lcs(c,d) -|c| - |d| 。c和d为a,b串的子串。lcs(c,d) 为c,d的最长公共子序列。解析:设f[i][j]:表示a串以i结尾 和b以j结尾的最长公共子序列长度。当a[i]==b[j]转移方程:f[i][j]=max(f[i][j],f[i-1][j-1]+2)因为a[i]==b[j] 那么前一个状态就是f[i-1][j-1] 。 |c|和|d|的长度都-1了 lcs(c,d)也-1了那么 4x -..原创 2020-11-16 19:59:50 · 335 阅读 · 0 评论 -
Intelligent Warehouse----------------------思维(dp+素数筛)
题意:给定n个数,选除最多的数,使得任何两个数都是倍数关系解析:设f[i]表示当前选的所有数都是i的约数得最大值假设当前f[4]=2 表示当前有2个数是4的约数那么f[4x]=max(f[4x],f[4]) (2<=x<=N/4) 4*x的约数也一定是2个但是x不能这样枚举 肯定TLE想一想任何一个合数都能由若干个素数乘积得到所以我们只需要乘素数倍即可总的时间复杂度(3e7+nloglogn)解析:#include<cstdio>#include&..原创 2020-10-31 21:16:06 · 170 阅读 · 0 评论 -
G - FatMouse‘s Speed HDU - 1160-------------------dp(最长上升子序列+记录路径)
解析:按照速度从大到小排序,然后根据体重跑最长上升子序列。在状态发生转移时,记录当前状态x由状态y转移过来最后倒着遍历记录的数组,即路径#include<bits/stdc++.h>using namespace std;const int N=1e6+10;int pre[N];struct node{ int x,y,id; bool operator < (const node &W){ return y>W.y; }}a[...原创 2020-10-21 16:38:27 · 222 阅读 · 0 评论 -
D - Redistribution-----------------------思维(dp)
解析:设f[i]:表示用3~i数凑出和为i的方案数f[i]=f[i-3]+f[i-4]+f[i-5]+…+f[i-i]#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=3000;const int MOD=1e9+7;ll f[N];int s;int main(){ cin>>s; f[0]=1; for(int i=3;i<=s;i++..原创 2020-09-14 15:14:50 · 157 阅读 · 0 评论 -
J - YJJ‘s Salesman-----------------------思维(树状数组+dp)
题意:给定n个坐标,每个坐标都有一个属性值。问你从(0,0)走到(1e9,1e9)属性之和的最大值你可以向右,向下,向右下走。只有向右下走才能获得属性值?问最大是多少?解析:这道题以看就是个dp。如果是个二维dp 那么状态方程f[i][j]=max(f[i-1][j],f[i][j-1],f[i-1][j-1]+v[i][j])但是这样是不可取的。所以我们就不枚举行了。我们按照x轴排序,y列从大到小遍历然后用树状数组维护[y-1,0]的最大值即可 然后dp下去#include<..原创 2020-08-21 17:47:11 · 292 阅读 · 0 评论 -
H - Skiing----------------------------思维(拓扑图+dp)
题意:给定n个顶点,和m条带权的有向边,问最长路?解析:这就是傻逼题,拓扑排序+dp就行了。细看代码#include <bits/stdc++.h>using namespace std;const int N=1e5+10;int e[N<<1],ne[N<<1],h[N<<1],w[N<<1],idx;int in[N];int t,n,m;int d[N];void add(int a,int b,int c)..原创 2020-08-17 23:08:36 · 149 阅读 · 0 评论 -
换根dp详解-------------------------思维
思路:首先这是个在树上用的东西,一般就是不告诉你哪个点作为根,而你就需要求出所有点作为根时的答案,然后才能得到最终的答案。思路也不是什么很神奇的东西:就是一开始先固定一个点作为根,然后 dp 一次求出解,然后利用这个解再做一次 dp——这次 dp我们称为换根,这次 dp 求出其他点作为根时的解。举例子: (此例子将会画图分析换根过程)题意:求1~n节点分别为根的最小深度和是多少解析:#include <bits/stdc++.h>using namespace std;原创 2020-08-07 12:16:34 · 1127 阅读 · 0 评论 -
Equal Sentences--------------------思维(dp)
解析:设f[i]:表示前i个字符组成相似字符串的个数当a[i]==a[i-1] f[i]=f[i-1] 因为a[i]和a[i-1]无法交换当a[i]!=a[i-1] f[i]=f[i-1]+f[i-2] 分别表示可以交换和不交换不交换f[i-1],可以交换f[i-2]#include <bits/stdc++.h>using namespace std;const int MOD=1e9+7;typedef long long ll;int t,n;ll f[2...原创 2020-08-06 11:38:41 · 133 阅读 · 0 评论 -
51nod 2534 最小旅行路线------------------------------dp
解析:设f[i][0/1]:表示0/1两个人走到美丽值为i的最短距离首先我们要知道的这两个人一开始必须都要在1的位置上。所以初始的状态方程f[1][0]=v[1][0]-1;f[1][1]=v[1][1]-1;v数组表示在美丽值为i的两个下标美丽值为1的我们不需要看了,我们现在讨论美丽值为2的C,D两个点有两种可能第一种B-C,A-D第二种A-C,B-D第一种递推方程:f[i-1][1]+abs(v[i][0]-v[i-1][1])+f[i-1][0]+abs(v[i][1]-v..原创 2020-07-30 16:48:08 · 224 阅读 · 0 评论 -
2366 砍树----------------------------------思维(树形dp)
解析:f[u]:表示以u为根的连通块的黑点数-白点数绝对值最大因为绝对值不好处理,所以我们分开来计算第一种就是给白色点填充1,黑色点填充-1 然后dfs记录每个节点为根的最大情况第二种就是给白色点填充-1,黑色点填充1 然后dfs记录每个节点为根的最大情况两种取最大值即可#include <bits/stdc++.h>using namespace std;const int N=5e5+1000;int f[N];int n,a[N];int d[N];int x,..原创 2020-07-29 10:59:45 · 234 阅读 · 0 评论 -
D. Unmerge---------------------------------思维(0/1背包)
题意:给你长度为2*n的p数组,p数组是根据a数组和b数组在规则下产生的规则ai<bi 将ai放到p数组,在a数组中删除aiai>bi 将bi放到p数组,在b数组中删除bi现在问你根据p数组,能否判断出是由两个长度为n的数组组成的解析:如果a[l~r] <b[i] 那么我们肯定优先选择a[l~r] 这一段同理 a[i]>b[l~r] 那么我们肯定优先选择b[l~r]这一段根据这个性质 我们从p[1]开始往后找第一个大于p[1]的数,我们给这块区间分段..原创 2020-07-24 10:27:17 · 137 阅读 · 0 评论 -
run--------------------------线性dp
解析:设f[i][0] 表示最后一步走到i米设f[i][1] 表示最后一步跑到i米解析f[i][0]既然最后一步是走的,那么前一步要么是跑的,要么是走的 那么状态转移方程f[i][0]+=(f[i-1][1]+f[i-1][0])解析f[i][1]既然最后一步是跑的,那么前一步只能走不能跑(因为题目要求不能连续跑2秒)那么状态转移方程就是:f[i][1]+=(f[i-k][0])然后在求一个前缀和即可#include<bits/stdc++.h>using name..原创 2020-07-11 19:39:58 · 223 阅读 · 0 评论 -
大水题-----------------------------dp(线性dp)
解析:设f[i][0/1] :表示第i个数,选与没选用map标记上一个相同数出现的位置状态转移方程:f[i][0]=max(f[i-1][0],f[i-1][1])f[i][1]=max(f[i][1],f[v[a[i]]][1]+sum[i]-sum[v[a[i]]]);f[i][1]=max(f[i][1],f[v[a[i]]][0]+sum[i]-sum[v[a[i]]-1]);#include<bits/stdc++.h>using namespace std;t..原创 2020-07-11 16:28:41 · 163 阅读 · 0 评论 -
问题 B: 分院帽 (hat)----------------------------思维(并查集+0/1背包)
题目描述在霍格沃兹魔法学校,每年都要举行分院仪式。分院帽今年不但负责将学生分到格兰芬多,赫奇帕奇,拉文克劳以及斯莱特林四个学院。还要把一部分学生分到新建起的一所学院 —— StandardDeviation学院。也就是离入学标准还差一点的学院。(因为想来学习魔法的人真的太多了,大约有n人)但即使是这样,也不能招收太多人,准确来说,学校打算招收m人。 可是,这是一所公平的学校,如果一些同分的学生中,只有一些被招收走了,那么学校将会颜面尽失。老师十分不好办。根据学校的记录,总共有k对人成绩相同,老师必须原创 2020-06-30 23:32:06 · 307 阅读 · 0 评论 -
加分二叉树-----------------------------区间dp
解析:根据二叉树性质中序遍历: 左(根)右题目要求中序遍历是1~n那说明一个性质 根的左子树节点编号都小于根根的右子树节点编号都大于根。根据这个性质我们可以枚举根那么递推方程: f[l][k-1] * f[k+1][r] + a[k]怎么输出前序遍历呢??我们另开一个数组记录当状态转移时根是哪个初始化: f[i][i]=a[i]其他的都 f[i][j]=1 因为题目要求某子树为空,加分为1(除叶子节点)#include<bits/stdc++.h>using nam..原创 2020-05-18 14:37:08 · 128 阅读 · 0 评论 -
E. K-periodic Garland------------------------思维(dp)
解析:设:f[i][0] 表示前i个合法,并且第i个字符为0的最小操作次数f[i][1] 表示前i个合法,并且第i个字符为1的最小操作次数状态转移方程:f[i][0]=min(f[i-1][0],f[i-1][1])+(s[i] == ‘1’)f[i][0]合法只需要i-1合法就行f[i][1]=min(pre[i-1],f[i-k][1]+pre[i-1]-pre[i-k])+(s[i] ==‘0’)f[i][1]合法只需要i-k的状态合法。如果i~k之间还存在1,那么我们肯定要把i ..原创 2020-05-15 21:34:27 · 355 阅读 · 0 评论 -
牛牛的01限定串--------------------------------dp
解析:介绍dp模型适用于01串,括号串,字符集为2的,最好出现个数对于该问题我们有n个0和m个1画一个n+1行,m+1列的图形然后往上面填数。对于0我们往下走,对于1我们往右走前缀相似可以按照这个走的路线走一次即可。对于后缀相似同理该问题就变成过河卒问题。从左上角走到右下角的最大值和最小值对于01限制,就是过河卒中只能向下和向右走的限制。我们现在从后往前递推思想和图片来自:https://ac.nowcoder.com/discuss/424000?type=101&...原创 2020-05-13 20:50:07 · 242 阅读 · 0 评论 -
Rinne Loves Edges---------------------------------树形dp
解析:题目给出一棵树,和一个点S,问删除哪些边使得叶子节点无法到达S,请输出删除边权最小的代价是多少那么分成两种情况设f[u]:表示删除以u为根的子树的叶子节点和根断开的最小代价第一种情况:假设当前节点为u,儿子节点为v。那么把儿子节点断开第二种情况:断开以u为根的子树中的叶子节点#include<bits/stdc++.h>#define x first#define y secondusing namespace std;const int N=1e5+10000;...原创 2020-05-13 10:28:29 · 179 阅读 · 0 评论 -
问题 E: bus------------------------------dp
题目描述两个球队的支持者要一起坐车去看球,他们已经排成了一列。我们要让他们分乘若干辆巴士,同一辆巴士上的人必须在队伍中是连续的。为了在车上不起冲突,希望两队的支持者人数尽量相等,差至多是D。有一个例外,就是一辆车上的人全部都是一个球队的支持者。问要将这N个人全部送至球场,至少要几辆巴士。输入第一行是整数N和D。接下来一行,按排队的顺序,描述每个人支持的球队,用H或J表示。该行没有任何多余的...原创 2020-05-06 22:25:09 · 244 阅读 · 0 评论 -
旅行青蛙-----------------------------------------dp
解析:最长不下降子序列#include<bits/stdc++.h>using namespace std;const int N=1e5+10;int a[N];int f[N];int q[N];int n;int main(){ cin>>n; for(int i=1;i<=n;i++) cin>>a[i];...原创 2020-05-06 20:02:30 · 204 阅读 · 0 评论 -
简单瞎搞题--------------------------思维(bitset优化dp)
解析:这道题可以看成背包问题 用bitset来优化内存,利用|运算相当于替代了加法。每当一个x加入进去,bitset保存的数都会和他进行或运算。最后我们只要统计有多少个1就行了。介绍一下bitset:bitset:011001 说明0,3,4这些数字存在 。所以本题最终统计有多少个1即可#include<bits/stdc++.h>using namespace...原创 2020-05-06 13:59:34 · 164 阅读 · 0 评论 -
括号-------------------------------经典dp
解析:设 f[i][j]:表示前i个位置还有j个左括号未匹配那么状态转移方程就是s[i]==’(’ f[i][j]=f[i-1][j-1]+f[i-1][j]s[i]==’)’ f[i][j]=f[i-1][j+1]+f[i-1][j]然后滚动数组优化#include<bits/stdc++.h>using namespace std;typedef...原创 2020-05-03 14:01:45 · 156 阅读 · 0 评论 -
训练技巧----------------------------单调队列优化dp
解析:f[i]:表示从前i件选,且合法的最大长度划分子集:1.不选第i件,那就选f[i-1]2.选第i件(包括i这段连续长度),假设选了x件 这段区间和相当于 s[r]-s[r-x+1]。那么r-x+1后面的就是f[r-x]这段状态是由前面状态递推而出的那么f[i]=f[i-j-1]+Si-Si-j转换一下就是f[i]=f[i-j-1]-Si-j+Si由于Si为固定值,对于f[i...原创 2020-05-01 10:29:07 · 180 阅读 · 0 评论 -
最大子序和-------------------------------单调队列优化dp
输入一个长度为n的整数序列,从中找出一段长度不超过m的连续子序列,使得子序列中所有数的和最大。注意: 子序列的长度至少是1。输入格式第一行输入两个整数n,m。第二行输入n个数,代表长度为n的整数序列。同一行数之间用空格隔开。输出格式输出一个整数,代表该序列的最大子序和。数据范围1≤n,m≤300000输入样例:6 41 -3 5 1 -2 3输出样例:7解析:对于长...原创 2020-04-30 20:07:26 · 173 阅读 · 0 评论 -
问题 F: 修理牛棚--------------------------线性dp
题目描述在一个夜黑风高,下着暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假,所以牛棚没有住满。 剩下的牛一个紧挨着另一个被排成一行来过夜。 有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。 自门遗失以后,农民约翰必须尽快在牛棚之前竖立起新的木板。 他的新木材供应商将会供应他任何他想要的长度,但是供应商只能提供有限数目的木板。 农民约翰想将他购买的木板总长度减到最少。给...原创 2020-04-30 11:19:11 · 243 阅读 · 0 评论 -
问题 G: 艰难取舍---------------------------------dp
题目描述由于hyf长得实在是太帅了,英俊潇洒,风流倜傥,人见人爱,花见花开,车见车载。有一群MM排队看hyf。每个MM都有自己独特的风格,由于hyf有着一颗包容的心,所以,什么风格的MM他都喜欢……但是,hyf有一个特别的要求,他不希望总是看到风格得差不多的MM,更加特别的是,如果两个MM风格完全一样,hyf不会有任何意见。现在,hyf希望从去看他的MM中,去掉一些MM,从而使得相邻2个M...原创 2020-04-29 11:21:12 · 265 阅读 · 0 评论 -
跳格子------------------------------dp
解析:第二次跳必须踩着第一次跳的台阶。那么说明第二次跳的台阶集合必定是第一次跳的台阶集合的子集。所以第一步我们可以预处理第一次跳,每次跳i的方案数假设vi那我们第二次我们枚举跳的距离.状态方程: f[i-1]*v1+f[i-2]*v2+f[i-3]*v3…fi-m]*vm#include<bits/stdc++.h>using namespace std;const ...原创 2020-04-27 13:18:49 · 452 阅读 · 0 评论 -
Beautiful Land--------------------------------dp(0/1背包处理背包体积过大)
解析:如果正常的0/1背包,体积过大,写不出来正常的f[i] 表示:选第i件物品最大价值由于题目给出体积超过1e6所以我们要反过来想0/1背包我们设f[i]表示装价值i需要最小的容量是多少。dp一下。最后我们只要判断最小的容量f[i]<=题目要求的容量即可#include<bits/stdc++.h>using namespace std;int t;c...原创 2020-04-26 17:26:29 · 165 阅读 · 0 评论 -
超越学姐爱字符串----------------------------线性dp
解析:设 f[i][0] :表示选cf[i][1]:表示选y状态转移方程:f[i][0]=f[i][0]+f[i-1][1] 因为不能连续cc 所以前一位必须是yf[i][0]=f[i][0]+f[i-1][0]+f[i-1][1] 因为放的y,前一位随便放#include<bits/stdc++.h>using namespace std;typedef long...原创 2020-04-25 20:16:10 · 247 阅读 · 0 评论 -
旅游--------------------------树形dp
解析:设f[u][0/1] 表示不选u和选u的方案数讨论一:选u,那么儿子节点v是不能选的 所以状态方程 f[u][1]+=f[v][0]讨论二:不选u,那么儿子节点v可以选,也可以不选,两者取最大 。状态方程 f[u][0]+=max(f[v][0],f[v][1])#include<bits/stdc++.h>using namespace std;typede...原创 2020-04-25 15:39:27 · 199 阅读 · 0 评论 -
问题 M: 【动态规划】数字分组I-------------------------------------0/1背包
题目描述给出一堆魔法石的重量,问如何分成两堆,使得它们质量和之差最小,求出这个最小值。输入第一行一个数n (n ≤30)。 接下来n行,每行一个正整数。(每个数≤100000)输出一个整数表示两组数字和的最小差。样例输入 Copy51 2 3 4 5样例输出 Copy1解析:转化为0/1背包问题。求出数组的和sum把问题转化成:背包的容量为sum/2,把数组的每个数字看成...原创 2020-04-21 17:42:19 · 769 阅读 · 0 评论 -
Music Problem--------------------------思维(bitset优化dp)
题意:给定n个数,问你是否能组成3600的倍数,如果可以输出YES 否则输出NO解析:用bitset优化dp 对每一个数都%3600 然后标记cur[x%3600]=1最后判断cur[3600]是否为1#include<bits/stdc++.h>using namespace std;int t,x;int n;bitset<10000> cur...原创 2020-04-14 22:57:23 · 184 阅读 · 0 评论 -
大家一起来数二叉树吧---------------------------------dp
解析:https://blog.csdn.net/qq_43690454/article/details/105292305跟这道题一样的套路设f[i][j]:表示i个节点,m个叶子节点的方案数状态方程:f[i][j]=f[i][j]+f[i-m-1][j-jj]*f[m][jj]m和jj 可以枚举#include<bits/stdc++.h>using namesp...原创 2020-04-03 15:02:06 · 189 阅读 · 0 评论 -
Hrbust 2095 奶牛家谱-------------------------------dp
农民约翰准备购买一群新奶牛。 在这个新的奶牛群中, 每一个母亲奶牛都生两个小奶牛。这些奶牛间的关系可以用二叉树来表示。这些二叉树总共有N个节点(3 <= N < 200)。这些二叉树有如下性质:每一个节点的度是0或2。度是这个节点的孩子的数目。树的高度等于K(1 < K < 100)。高度是从根到最远的那个叶子所需要经过的结点数; 叶子是指没有孩子的节点。有多少不同的...原创 2020-04-03 14:25:23 · 210 阅读 · 0 评论 -
黑白树-----------------------------------------------树形dp
解析:染色肯定自下往上染,所以我们要从叶子结点开始染色。当一个节点染完色后,要更新父节点的染色值(因为有可能儿子节点染色值大于本身,这会让答案更优)染色值往上传递是要-1的递推方程 k[fa]=max(k[fa],k[u]-1)#include<bits/stdc++.h>using namespace std;const int N=1e5+10000;vecto...原创 2020-04-03 11:58:09 · 175 阅读 · 0 评论 -
合并回文子串------------------------------------思维(区间dp求最长回文字符串)
本篇先讲述:动态规划求解最长回文字符串长度令f[i][j]:表示s[i]至s[j]所表示的子串是否为回文串,是为1,否为0.根据s[i]和s[j]是否相等划分子集1.s[i]==s[j],那么只要s[i+1]至s[j-1]是回文子串,那么s[i]至s[j]一定是回文子串。如果s[i+1]至s[j-1]不是回文子串,那么s[i]至s[j]也一定不是回文子串2.s[i]!=s[j] 那么s...原创 2020-04-03 00:02:16 · 265 阅读 · 0 评论 -
被3整除的子序列-----------------------------dp(整除倍数型dp求方案数)
解析:这种线性dp也是一个套路题突破口:对3的余数处理f[i][02]:表示前i个数之和%3余(02)的所有情况所以我们只要枚举余数的状态即可状态转移方程:f[i][j]=f[i-1][j]+f[i-1][(j+3-m)%3]f[i-1][j]:表示第i个数不选,选第i-1个且余数为j的f[i-1][(j+3-m)%3] :表示第i个数选,因为我们枚举的是j,我们要判断第i-1...原创 2020-03-30 16:23:58 · 156 阅读 · 0 评论 -
问题 F: 篮球运动----------------------------------------思维(dp)
题目描述小明建造了一个篮球场,他请来了2行n列的人,想让他们进行比赛。每一个人都有一个能力值,第一行分别为h11,h12,…,h1n,第二行为h21,h22,…,h2n。现在小明可以选一些人组成一个最强团队。但是选人是有规则的,因为选一个人会让附近的人都很妒忌,所以他既不会同一行里连续选择2个人,也不会同一列里的连续选择2个人。现在他希望所选团队的能力值的之和最大,但人太多了,所以他想请聪明的...原创 2020-03-29 14:20:32 · 259 阅读 · 0 评论 -
操作集锦------------------------------------------------思维(方案数dp)
解析:设f[i][j]:表示选第i个字符,长度为k的且本质不同的子序列方案数状态方程:f[i][j]=f[i-1][j]+f[i-1][j-1] 不选s[i]/选s[i]但是会有重复的,我们用last记录字符之前出现过的位置。然后减去那部分f[i][j]-=f[last-1][j-1]f[last-1][j-1] 就相当于重复的方案数加上第i个字符#include<bit...原创 2020-03-28 10:28:04 · 99 阅读 · 0 评论 -
First Last Sorting--------------------------------------思维
题意:给你n个数的排列,每次只能把元素移动最前面或着最后面,请问至少移动几次使得n个数升序解析:突破口:严格递增的子序列是不需要移动的.例: 8 3 6 7 4 1 5 2严格递增的子序列(3,4,5)逆向思维找出最长的严格递增的子序列 然后用n减去,就是我们需要移动的次数#include<bits/stdc++.h>using namespace std;co...原创 2020-03-26 12:42:21 · 131 阅读 · 0 评论