![](https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
文章平均质量分 53
seez
njfu
展开
-
P3092 [USACO13NOV]No Change G(状压dp+二分)
[USACO13NOV]No Change G - 洛谷由于需要顺序的付完N个物品,那么说明具有单调性,二分一下就好了我们可以思考怎么定义状态不妨让状态定义为当前最多付了多少物品,这样子就可以保证单调性了#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N = 17, M = 1 << 17;c...原创 2022-02-27 15:19:04 · 445 阅读 · 0 评论 -
牛客寒假训练营1 K 冒险公社(线性dp)
先从样例模拟清楚题意:...最后模拟可以得到答案4题意:求前n个岛中最多的绿岛数,根据罗盘预测结果知道实际上绿岛数dp做法由于dp问题的使用条件是1.最优子结构 2.不具有后效性本题是一个线性递推的过程,存在最优子结构由于处于某一点时,当前的状态(什么颜色) 是会影响到后面两座岛屿的所以我们可以多开几维,因为颜色就只有三种,可以枚举出来最后的时间复杂度是O(n*3^4)原问题:考虑前n个岛屿后,最多的绿岛数子问题:考虑前i个岛屿,且i为...原创 2022-01-25 13:39:26 · 318 阅读 · 0 评论 -
292.炮兵阵地(棋盘类状压dp)
292. 炮兵阵地 - AcWing题库分析:限制条件:考虑上下 同一列两格内不能放 不能 (x>>i&1) && ((x>>(i+1)&1) || (x>>(i+2)&1)) 考虑左右 同一行两格内不能放 要满足 (a&c|a&b|c&b)==0 只能在平原上面放状态表示:已经摆放完前i-1,且第i-2行与第...原创 2022-02-27 13:50:03 · 356 阅读 · 0 评论 -
327. 玉米田 (棋盘状压dp)
分析:限制条件:由于不能有公共边缘,并且只有在肥沃的土地上才可以种植,那么必须满足下面三种限制条件只能在肥沃的土地上种 不能 x>>i&1 && a[i][line]==0 同一列 不能连续种植 不能 x>>i&1 x>>i+1&1 同一行 不能连续种植 a&b==0初始化:0边界:dp[0][0]=1比较直观的is_valid()方法#include &l...原创 2022-02-27 11:55:13 · 254 阅读 · 0 评论 -
1064.小国王 (棋盘状压dp)
原题链接分析:一个棋盘状压dp问题,由于放置一个国王,国王不能攻击周围8个格子,那么一共有以下三种情况考虑上下 同一列相邻的位置不能放置国王 即(x>>i&1)&&(x>>(i+1)&1) 不能同时成立 考虑左右 同一行相邻的位置不能放置国王 即相邻两列状态 (a&b)==0 考虑四个顶点 也就是相邻两列的并集(a|b) 必须满足情况1维护的状态:当前列号,当前列的状态...原创 2022-02-27 11:08:18 · 256 阅读 · 0 评论 -
524. 愤怒的小鸟(重复覆盖,集合类状压dp)
524. 愤怒的小鸟 - AcWing题库关键:枚举所有的情况会超时,只需要枚举必要的中间状态,使得结果正确即可步骤:预处理出所有的抛物线 状态压缩dp分析:由于抛物线一定通过原点(0,0),任意两个小猪的坐标都可以组成一个抛物线开头向上 (a<0) 经过原点(0,0) 只有一个点时,可以看成直线同时,由于任意两个点之间是构成抛物线的,并且一条抛物线上可能有多个小猪一条抛物线上有多个小猪 两个点x不能相同,否则够不成抛物线那么,有两个点可以推出抛物线的公式...原创 2022-02-25 14:00:43 · 330 阅读 · 0 评论 -
P3694 邦邦的大合唱站队(集合类状压dp)
邦邦的大合唱站队 - 洛谷关键:由于是线性安排的,通过枚举所有M的选择情况+最后一个不同点,可以达到枚举M的所有摆放顺序分析:由于M的范围是1~20,所以想到用状压dp来做由于按照出队后,出队的偶像可以归队到任意的空位中,且我们需要同一乐队的偶像连续站在一起性质1:一队偶像安排到的位置可以是任意的,在他之前和之后的偶像都可以是任意的因为位置可能是任意的,那么我们可以先从头开始安排,一直安排到尾。因为我们是使用状压dp来做的,通过枚举所有 2^j (0<=j<...原创 2022-02-25 11:33:13 · 529 阅读 · 0 评论 -
291. 蒙德里安的梦想(状压dp)
291. 蒙德里安的梦想 - AcWing题库分析:由于数据范围是1~11,dfs会超时,可以想到状压dp核心:先放横着的,再放竖着的 总方案数=只放横着的小方块的合法方案数合法情况:没有填放小方块和没有前一行小方块延伸的位置,能够用竖着摆放的小方块填充满,就是空着的位置需要是偶数个当前列状态和前一列状态,同一位置上没有两个1 j&k==0 同一列连续空着的小方格是偶数或者0 j|k 是否合法由于第i...原创 2022-02-23 10:48:02 · 689 阅读 · 0 评论 -
1205. 买不到的数目(dp)
1205. 买不到的数目 - AcWing题库根据最后一个使用的糖果作为划分依据,可以划分出不重不漏的两个子集使用糖果1 使用糖果2#include <iostream>#include <algorithm>using namespace std;const int N=1e7+10;bool dp[N];int a[N];int main(){ for(int i=1;i<=2;i++) cin>>...原创 2022-02-22 17:31:00 · 109 阅读 · 0 评论 -
1022. 宠物小精灵之收服(二维背包,<m)
原题链接其实是一个普通的01背包问题,主要的坑点在于二维费用 有一维的费用条件是<m由于受到的伤害不超过m,可以先让m--,因为最后要求的是皮卡丘剩余的血量,皮卡丘可能是满血状态,所以枚举时候要从0开始枚举for(int i=1;i<=m;i++) for(int j=0;j<k;j++) if...原创 2022-02-21 16:53:13 · 510 阅读 · 0 评论 -
P1120 关路灯(区间dp,前缀和)
#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N=55;typedef long long ll;ll p[N],w[N];ll dp[N][N][2];int main(){ int n,c; cin>>n>>c; for(int i=1;i<=n;i++) cin&...原创 2022-02-21 09:10:01 · 475 阅读 · 0 评论 -
CF 607B Zuma(区间dp,回文子串数量)
Zuma - 洛谷分析:运用分析元区间开始,逐步思考区间合并与状态转移方程len==1时,每个元区间被消耗时间都是1 len==2时,如果两个相等,消耗时间为1,两个不相等,消耗时间为2 len==3时,会有一个2区间和一个1区间合并(枚举中断点),如果左右端点相等,dp[i][j]=dp[i+1][j-1] ...通过上面的规律发现,分析图如下状态计算/子集划分:根据枚举区间大小,我们发现区间合并时由两个独立的,大小不一定相等的,子区间合并。所以,状态转移方程应该是枚举..原创 2022-02-21 09:06:32 · 224 阅读 · 0 评论 -
1058. 股票买卖 V(状态机模型)
原题链接#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N=1e5+10;int w[N];int dp[N][3];int main(){ int n; cin>>n; for(int i=1;i<=n;i++) cin>>w[...原创 2022-02-18 21:50:38 · 157 阅读 · 0 评论 -
1057. 股票买卖 IV (状态机模型)
1057. 股票买卖 IV - AcWing题库#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N=1e5+5;int w[N];int dp[102][2];int main(){ int n,k; cin>>n>>k; for(int i=1...原创 2022-02-18 21:30:11 · 191 阅读 · 0 评论 -
1049. 大盗阿福(状态机模型)
原题链接#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N=1e5+10;int a[N];int dp[N][2];void solve(){ int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i];...原创 2022-02-18 20:36:30 · 107 阅读 · 0 评论 -
P3146 [USACO16OPEN]248 G (区间dp)
[USACO16OPEN]248 G - 洛谷题意:每次合并两个 相同的,相邻的 元素,合并后的数值+1,求序列中合并后出现的最大数字的值是多少分析:其实可以很自然的想到了 区间dp,因为和石子合并有很多共同之处,只要在石子合并的基础上思考就可以了由于我们每次只能合并相同的且相邻的元素,那么对于不同的元素自然是不能合并的,我们可以在石子合并的基础上思考,把一个区间内的所有数合并成一个数字。剩下的就是区间dp了边界:len==1 dp[i][j]=w[i]初始化:全部初始化为0...原创 2022-02-17 13:50:20 · 479 阅读 · 0 评论 -
小小粉刷匠(区间dp)
原题链接可以看到本题和 涂色paint 的题目,只有一点不一样,就是本题限制了粉刷的长度,对于两个相同颜色的段,如果距离超过了k,那么就不能一起染色了一种解决方法是:特判如果距离超过了k,那么可以看成这两个是不同颜色,需要染色两次,使用涂色paint 题目中对待不同颜色的方法就可以了这里的枚举中断点:其实是枚举某个中断点,在中断点左边的染了一次s[i],中端点右边的染了s[j]枚举在哪里作为这个中断点比较好。(这里中断点分割开的两个子集:dp[i][k],dp[k+1][...原创 2022-02-17 13:00:37 · 338 阅读 · 0 评论 -
P4170 涂色(区间dp,两点+断点)
[CQOI2007]涂色 - 洛谷分析:首先可以想到是一个区间dp的问题,区间dp的问题的递推是从长度较小的区间一步步递推到长度最大的区间的,对于长度较小的区间,可以先模拟一遍可能的递推方式len=1时此时一定要染色,dp[i][j]=1len=2时 ,此时合并两个len=1的区间颜色相同时,dp[i][j]=min(dp[i+1][j],dp[i][j-1]); 颜色不相同时,此时的染色次数==2len=3时,此时合并一个len=1的区间,一个len=2的区间如果左右两个端点..原创 2022-02-17 11:48:54 · 587 阅读 · 0 评论 -
合并回文子串(区间dp)
原题初始化:全部初始化为false边界:lena+lenb<=1 初始化为1#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N = 55;bool dp[N][N][N][N];void solve(){ string a, b; cin >> a >> b; int n = ...原创 2022-02-17 11:12:37 · 296 阅读 · 1 评论 -
P3205 [HNOI2010]合唱队 (区间dp)
[HNOI2010]合唱队 - 洛谷分析:根据题意我们发现,小a每次排队的时候,会出现两种情况当前排入的人比初始队列中前一个人矮,排到最左边 当前排入的人比初始队列中前一个人高,排到最右边现在给定我们一个理想队列,然后根据这个理想队列推理出有多少种初始队列根据这个理想队列,其实我们可以发现,固定住一个点之后,初始队列在他后面的人,一定是不断加入到这个点左右两边的。所以固定住这个点之后,可以模拟不断向左向右加人,来获得理想队列。加人实际上就是一个区间左右端点的问题于是就可以从理想...原创 2022-02-16 20:09:09 · 611 阅读 · 2 评论 -
多个不相交子段和问题(状态机模型)
题意:给定一个数组,找出m个不相交的子段的和的最大值问题如果对于每个子段都必须是相连的(即每个元素都必须被选)的情况,状态可以如下定义这样子的时间复杂度是O(n^2m),如果要优化的话,可以维护一个maxn[i][j],维护一个前缀最值的数组,这样子的话可以优化到O(nm)如果对于一个元素可以不选的情况,可以如下定义,下面的定义也可以解决上面的问题for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { ..原创 2022-02-16 15:25:14 · 198 阅读 · 0 评论 -
1489. 田忌赛马 (贪心,区间dp)
题目:田忌赛马的故事,田忌每次输一局要付200元,赢一局获得200元,平局获得0元问,田忌和齐王都有n匹马的情况下,最多可以获得多少元1489. 田忌赛马 - AcWing题库由于田忌赛马的故事背景,我们很快就能够想到合理的贪心策略,上等马对中等马,下等马对上等马,所以可以将齐王和田忌的马都按照从大到小降序排序那么排序之后,对于田忌当前最大的马,如果比齐王最大的马还快,就用。如果田忌当前最大的马,如果比齐王最大的马还慢,就用田忌最小的马。证明: 当前都是按照降序排序,田忌目前的.原创 2022-02-16 13:41:08 · 982 阅读 · 0 评论 -
nc1033-小A的回文子串(环,区间dp)
原题链接由于是回文子串问题,首先要思考怎么进行回文字串问题的处理子串:连续的 子序列:不连续的对于子串可以采用类似子序列的方法边界处理不太一样初始化:全部为false边界:len==1 设置为true len==2且s[i]==s[j],dp[i][j]=true#include <iostream>#include <algorithm>using namespace std;const int N = 5010;bool dp[2...原创 2022-02-16 10:21:08 · 85 阅读 · 0 评论 -
1222. 密码脱落(区间dp,括号匹配)
可以看出是一个括号匹配/最长回文子序列的模板题初始化:全部定义为0边界:由于单个字符也算是回文子序列,dp[i][i]=1状态计算/子集划分:根据两端的字符是否在最长回文子序列中,可以不重不漏的划分成以下四个子集s[i]和s[j]均在回文子序列中 dp[i][j]=max(dp[i+1][j-1]+2) s[i]在回文子序列中 dp[i][j]=max(dp[i][j-1]) s[j]在回文子序列中 ...原创 2022-02-15 17:42:58 · 220 阅读 · 0 评论 -
734.能量石(贪心,背包)
一个能量石有自己的l,e,s,可以想到01背包问题,由于01背包是线性递推的,思考有没有一种排序的方法,能够使得我们能够贪心的获得最多的能量?可以想到邻项交换法,通过交换两个能量石,查看能不能推出关系式如图可以得到关系式,得到后排个序,做一个01背包即可#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N=10...原创 2022-02-15 16:40:04 · 161 阅读 · 0 评论 -
321. 棋盘分割(二维区间dp)
321. 棋盘分割 - AcWing题库题意:一个矩阵可以横切,或者侧切,如图所示 对于被切开成两个部分的棋盘,可以且只能选择一个继续向下切求方差最小,由于均方差X固定,n固定,要计算的是被分成的子矩形的面积(xi-X)*(xi-X)。所以,可以采用搜索的方法,不断地枚举出最小值分析:二维区间dp,其实类似于数字三角形模型,由于分割可能不具有线性递推的关系,所以采用记忆化搜索的方法。横切i,分为两部分[(x1,y1)~(i,y2)],[(i+1,y2)~(x2,y2)]...原创 2022-02-15 15:57:57 · 580 阅读 · 0 评论 -
479. 加分二叉树(树上区间dp)
479. 加分二叉树 - AcWing题库分析:条件/性质:中序遍历 1,2,3...n 左右子树为空 ,积分=1 子树的积分=左*右+根根据中序遍历是1,2,3...n,可以分为以下的情况根结点=k,左边区间全部为l,右边区间全部为r,左右区间相互独立互不干扰那么,就可以转换为区间dp,石子合并的模型,寻找中断点作为根结点需要注意是子树为空的情况,子树为空时需要特殊考虑状态表示:dp[i][j]表示所有中序遍历顺序为i~j的集合递推顺序:1<...原创 2022-02-15 14:03:13 · 740 阅读 · 0 评论 -
1069. 凸多边形的划分(思维,区间dp)
限制条件:分为N-2个三角形 互不相交分析:由于一个三角形是需要三个顶点,我们可以先枚举三个顶点,然后观察一下有什么性质如图,当我们枚举出i,j,k三个顶点的时候,当前可以划分为三个集合左边的多边形集合+右边的多边形集合+当前的三角形这样子看就和能量项链很像了,通过枚举三个点,然后计算集合,由于需要先计算出所有的单个三角形的集合 然后 再递推到一整个多边形中的权值(枚举两个端点,至少中间间隔一个点,所以len为3,才能保证中间间隔至少一个点)所以len至多从3开始枚举...原创 2022-02-15 13:08:09 · 518 阅读 · 0 评论 -
320. 能量项链(环形,区间dp)
320. 能量项链 - AcWing题库分析:可以看成一个环形的区间dp问题一共有4个珠子,如图有四个标记,可以合并到最后只剩下2个标记,也就是1个珠子为止。那么最少是需要3个标记才可以继续合并,如果小于三个标记就不用再合并了。状态表示:所有合并i~j个标记的集合状态计算/划分依据:根据i~j中间的标记可以划分为不重不漏的j-i-1个集合,由于i,j表示的是标记,所以不能参与合并(dp[i][i]不是一个珠子,不参与运算,所以dp[i][j],j>=i+1)i+1作为...原创 2022-02-14 22:29:56 · 364 阅读 · 0 评论 -
1068. 环形石子合并 (环形,区间dp)
原题链接- AcWing分析:与石子合并只加了一个环形的条件对于环形问题,如果只是枚举中断点的话,在石子合并的基础上多开一维,时间复杂度是O(n^4)可以采用一个普遍的方法,就是把环转换成一个链通过把从1展开的链接在n的后面,这样子枚举的时候枚举以 位置2 断开的链,只需要枚举 以2开始,长度为len的链,就可以枚举n与1相邻的情况了状态转移方程基本和石子合并一样,不同点在于环的存在,导致循环枚举不同for(int len=1;len<=n;len++) ...原创 2022-02-14 21:45:00 · 309 阅读 · 0 评论 -
282.石子合并 (区间dp)
运用区间dp的思想来思考状态表示:所有合并第i堆到第j堆果子的集合属性:min状态计算/子集划分:上一次合并了哪两堆果子,即上一次的中断点是哪中断点在i+1 合并[i]和[i+1,j] dp[i][j]=dp[i][i]+dp[i+1][j]+sum[i,j] 中断点在i+2 合并[i,i+1]和[i+2,j] dp[i][j]=dp[i][i+1]+dp[i+2][j]+sum[i,j] ... 中断点在j-1 合并...原创 2022-02-13 22:19:55 · 232 阅读 · 0 评论 -
1252. 搭配购买(并查集,特殊依赖01背包)
分析:可以看成是特殊的有依赖的背包问题,因为有依赖的背包对于子树是可选可不选,这里是必选全部选,反而变得更加简单了所以我们可以把一堆搭配看成一个集合,然后运用并查集维护并查集的拓展域,做01背包问题并查集拓展域价格域 v ==集合中所有价值和 价值域 w ==集合中所有价格和#include <iostream>#include <algorithm>using namespace std;const int N=10010;int v[N]; ...原创 2022-02-07 18:16:49 · 354 阅读 · 0 评论 -
牛客寒假训练营 3 C (多项式,逆dp)
原题链接我们可以很自然的想到逆向思维首先是逆拓扑时,我们的状态计算图如下可以分为 不买 , 买半个 , 买整个 三个子集所以对于背包容积为m的背包来说,瓜最多重2m然后是正拓扑时,因为一个集合可以递推到三个集合,我们就可以从一个集合找到他的三个父集合,那么在递推的时候,就可以使用正向递推算出答案正向递推:#include <iostream>#include <algorithm>#include <vector>...原创 2022-02-07 15:58:45 · 471 阅读 · 0 评论 -
10. 有依赖的背包问题(树形背包)
10. 有依赖的背包问题 - AcWing题库限制条件:选择子结点必须先选择父节点 选择的物品总体积不能超过m对于所有子树,有两种选择,选或者不选,使用dfs的话,最坏情况是O(2^100),所以我们选择dp,以不同的体积作为集合的划分依据,只留下每个集合的最大值,这样子就可以合理的优化所以我们可以得出,在选择一个结点之前,必须先选择他的父结点,才能对他做01背包状态表示:对以u为根结点的树选择,并且体积不超过j的所有方案状态计算:根据最后一个不同点来进行状态划分选了u...原创 2022-02-02 11:15:52 · 1270 阅读 · 0 评论 -
285. 没有上司的舞会(树形dp)
#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N=6005;int dp[N][2];int a[N];int ne[N],e[N],h[N],idx;bool st[N];void add(int a,int b){ e[idx]=b; ne[idx]=h[a]; h[a]=idx++;...原创 2022-02-01 21:03:39 · 183 阅读 · 0 评论 -
11. 背包问题求方案数(最优解方案数)
11. 背包问题求方案数 - AcWing题库分析:需要求最优解的方案数,其实也是一个动态规划的过程首先求出背包问题的最优解 动态规划求方案数状态计算:根据最后一个不同点进行划分,也就是对于a[i]的选择情况进行划分选的情况优于不选 cnt[i,j]=cnt[i-1,j-v] 选的情况==不选 cnt[i,j]=cnt[i-1,j]+cnt[i-1,j-v] 选的情况<不选 cnt[i,j]=cnt[i-1,j...原创 2022-02-01 20:51:29 · 653 阅读 · 0 评论 -
7. 混合背包问题
7. 混合背包问题 - AcWing题库对于混合背包问题,其实就是三种背包一起用,但是这里难点在于,多重背包需要二进制优化#include <iostream>#include <algorithm>using namespace std;const int N=1005;int dp[N];int main(){ int n,m; cin>>n>>m; for(int i=0;i<n;i++) ...原创 2022-02-01 20:21:33 · 123 阅读 · 0 评论 -
532. 货币系统(bool型完全背包,贪心)
原题链接分析:对于两个等价的货币系统来说,有以下限制条件对于任意一个非负整数x,要么都可以表示,要么都不可以表示于是可以得出引理,对于两个等价的集合A,B(B表示被简化的系统)A集合中不能被A中其他元素凑出来的数,一定会出现在B集合中 A集合中能被A中其他元素凑出来的数,一定不会出现在B集合中引理1证明:A集合与B集合等价的条件是凑出的数相同,不能凑出的数也相同反证:假如B集合中存在一个不在A集合中且不能被A集合表示出来的数,那么这个数就不能被A集合表示出来,凑不出来,由...原创 2022-02-01 19:59:25 · 421 阅读 · 0 评论 -
487. 金明的预算方案(分组背包)
限制条件:一个主件有多个附件,可以选择不买和买几个 必须先购买主件再购买附件所以对于一个主件最多有四种选择这里使用位运算枚举所有选择,也可以用爆搜枚举for(int y=0;y<1<<servent[i].size();y++) { int vv=master[i].first,ww=master[i].first*master[i].second; for(int z=...原创 2022-02-01 16:41:20 · 370 阅读 · 0 评论 -
1013. 机器分配(分组背包原理,输出方案)
原题链接e分析:分组背包问题是互斥选择模型,即一个物品组内只能做出一种决策选择,叫做分组背包问题分组背包问题,如果运用分组背包模型来做的话,如下转换每个公司看成一个物品组,我们至多可以选择m个,选择0~m个操作是互斥的,只能做一个,因此对于分给第 i个 公司 的不同 机器数量 可以分别看作是一个 物品组 内的 物品状态计算初始化:全部初始化为0状态计算:根据最后一个不同点/最后一次选择来进行划分,可以划分为以下子集当前选择0个...原创 2022-02-01 15:52:04 · 764 阅读 · 0 评论