![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
DP
文章平均质量分 55
最菜的acmer
这个作者很懒,什么都没留下…
展开
-
Educational Codeforces Round 21 -DEG
D题大意就是把物品分成两堆然后能否从大的一堆里面拿出一个给小的一堆似的两堆数相等 题解思路:用set容维护两个堆哪一堆大就从里面找是否有一个数等于大的一堆的值 减去总值的一半 当然如果总值为奇数肯定分不了的 题目链接#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<set>#i原创 2017-05-18 21:13:25 · 210 阅读 · 0 评论 -
HDU - 3507(斜率DP优化)
题解:用dp[i] = min(dp[i],dp[j]+(sum[i]-sum[j])^2+M)来动态规划但是n有50W一个一个试肯定超时,但是对于形如 dp[i]=min{dp[j]+f(i,j)}的方程,无法做到O(1)计算dp[j]+f(i,j)的最小值,这时就需要斜率优化这个技巧来解决这个问题了。 令k Y(j)−Y(k)/(X(j)−X(k))优化方法原创 2017-10-26 23:32:57 · 242 阅读 · 0 评论 -
HDU - 2829(斜率优化DP)
题解:用f[i]表示a[1]^2+a[2]^2+...a[i]^2,sum[i] = a[1]+a[2]+...a[i];dp[i][j] = min(dp[i][j],dp[i-1][a]+((sum[j]-sum[a])*(sum[j]-sum[a])-f[j]+f[a])/2));然后一个一个试的话是1e9会超时可以用斜率换算一下就是(2*dp[j][b]-2*dp[j][a]+sum[原创 2017-10-26 23:47:54 · 513 阅读 · 0 评论 -
HDU - 2993 (斜率DP+读入优化)
题意:求给n个数的序列求最大的连续k个数的平均值题解:n很大肯定不能一个一个试所有但是是我们发现(pre[i]-pre[j])/(i-j)如果把i,j看着横坐标pre[i],pre[j]看做纵坐标的话就是求斜率了,然后此时可以用斜率优化一下如下图然后我们就可以在去头的是当队列的第二个满足第一个图的条件就可以去掉队列头,在加入i的时候如果i满足第二个图的条件就可以把对尾去掉了原创 2017-10-27 22:22:38 · 278 阅读 · 0 评论 -
UVALive - 5097(斜率DP)
题解:先把宽按从大到小排序如果宽相同就按高度从大到小排序,接着把宽度和高度都小于某个点的删除掉,然后就可以求出方程就是dp[i][j] = min{dp[i-1][a]+x[a+1]*y[j]};然后斜率优化的的话用队列维护可以化为dp[j]+x[j+1]*y[i]=(dp[i]-dp[c])*(x[c+1]-x[b+1]),i>b>c就可以把队尾的的b删除掉#include#inclu原创 2017-10-27 22:48:33 · 295 阅读 · 0 评论 -
Wannafly挑战赛1A-(树形DP)
题解:从叶子结点到根计算一下每个子结点的从该结点开始计算深度是偶数深度是奇数的个数即可,然后顺便求一下这个点下面深度是奇数的总个数和偶数的总个数即可然后方案数就是每个点的下面点奇数个数乘上奇数个数,偶数个数乘偶数个数#include#include#include#includeusing namespace std;typedef long long int ll;#原创 2017-10-13 23:14:42 · 265 阅读 · 0 评论 -
CodeForces - 149D(区间DP)
题意:给你一个完整的括号匹配让你涂色,涂色的条件是一个括号必须涂一边,而且只能涂一边。相邻的颜色不能相同而且只能涂蓝色和红色,然后求涂色方案数题解:用思维然后dp[l][r][lc][rc]表示我此时涂的是第l到第r个括号边,lc表示之前左边涂的颜色,rc表示之前右边涂的颜色,0表示没涂,1表示涂蓝,2表示涂红色然后判断l和r是在同一个括号,两个相邻的括号,两个括号不相邻的这些情况怎么原创 2017-11-10 23:50:55 · 375 阅读 · 0 评论 -
POJ - 1651(区间DP)
题意:每次从里面抽取一个数然后和相邻两个数相乘求出最小值,直到只剩头尾两个数题解:dp[l][r]表示从l到r个数抽取一个数然后响铃两个数相乘最小值,用0表示还没有遍历过记忆化搜索那么转移方程就是dp[l][r] = a[i]*a[l]*a[r]+dfs(l,i)+dfs(i,r); 取其中的最小值即可#include#include#include#includeusin原创 2017-11-10 23:59:23 · 218 阅读 · 0 评论 -
POJ - 2373(线段树+DP)
题目: 约翰的奶牛们发现山督上的草特别美味.为了维持草的生长,约翰打算安装若干喷灌器.为简化问题,山脊可以看成一维的数轴,长为L(1≤L≤10^6),而且L-定是一个偶数.每个喷灌器可以双向喷灌,并有确定的射程,该射程不短于A,不长于B,A,B(1≤A≤B≤103)都是给出的正整数.它所在位置的两边射程内,都属它的灌溉区域.现要求山脊的每一个区域都被灌溉到,而且喷灌器的灌溉区域不允许重叠, 约翰有原创 2017-10-16 23:09:23 · 400 阅读 · 0 评论 -
fjnu1233(dp+逆元)
题解:因为操作n次,然后最终长度为s的长度len,那么我们可以暴力求出不管是否跟s一模一样只要长度一样然后求出这样的方案数除以2^len即可转移方程dp[i][j]的方程就是 当j不为0时候dp[i][j] = 2*dp[i-1][j-1]+dp[i-1][j+1],当j为0时就是dp[i][j] = dp[i-1][j]+dp[i-1][j+1]即可,题目要求我们取膜所以我们要求逆元然后乘以原创 2017-11-26 23:21:03 · 206 阅读 · 0 评论 -
UVALive - 4015(树形DP)
题意:给你一颗带有权值的树,接着一个有能量的机器人,每经过一个边就要消耗对应权值的能量,求你x点能量最大能经过你几个结点题解:我们可以dp出我 走i个点消耗最小的能量,因为我只有两种情况要么从另外一颗子树经过 j个结点然后走回来或者从另外一颗子树走j个结点不会来,所以我们要记录一些该节点走j个结点回来的最小值和不回来的最小值,接着可得转移方程就是dp[u][i].fi = min(dp[u][i-...原创 2018-02-11 14:37:05 · 193 阅读 · 0 评论 -
hdu2668
题解:用两个指针移动判断右指针移动到r位置,l位置最小能在哪里然后就是r-l+1,取其中最大值即可#include<iostream>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<cstdio>#include...原创 2018-02-11 14:59:21 · 175 阅读 · 0 评论 -
ZOJ - 4007 (树形dp)
题意:给你一颗树然后,树上的点有权值1,0,-1,-1可以换成0或者1,然后每条变连接的两个点权值如果不一样那么答案加一,让你求把1怎么变使得最后的答案最小题解:树形dp,分为几种情况如果树上的权值如果为0的话转移方程为:dp[0][u] += min(dp[1][v]+1,dp[0][v]),如果为1的话转移方程为:dp[1][u] += min(dp[1][v],dp[0][v]+1),如果为...原创 2018-03-15 21:24:38 · 216 阅读 · 0 评论 -
牛客练习赛13
A:找一下4的个数还是7的个数多,如果7多就输出7否则输入4,两者都没有就输出-1#include<iostream>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<cstdio>#include<cmat...原创 2018-03-18 19:08:04 · 147 阅读 · 0 评论 -
ZOJ - 4011(DP)
题解:dp[i][j]表示放了i个数最后一个数字是j然后 转移方程就是dp[i][j] = dp[i][j] + dp[i-1][k] k是j的所有因数#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<vector>usi...原创 2018-03-13 23:15:20 · 260 阅读 · 1 评论 -
ZOJ - 3949(树形dp)
题解:我们先求出所有根到所有树上路径的总值,最后我们需要求的是加到哪条边上面的值后权值最小,假设根是第0层,u是第n层,求第i层会开始变少那么,数值应该是 n-i+1-i<0 =》 (n+1)/2 < i那么如果当n是奇数的话那么应该从(n+1)/2+1层开始他的子树的路径要都要减去2,4,6,8。。。2*m,,如果当n是偶数的话i应该从第(n+1)/2层开始他的子树路径减少1,3,...原创 2018-03-27 21:25:15 · 284 阅读 · 0 评论 -
hdu6331(最短路)
题意:给你一个有向图让你,有q次查询让你求从u到v至少经过k条路径的最短路径。题解:这里注意到我们最大的环就是1->2->3->n....->1这样一个n条路径的环,所以当经过k~k+n条路径找不到答案的话就肯定没有结果,因为k最大10000所以我们根据分块思想分成,也就是每100分成一块,那么我们可以预处理f[i][j][k],表示走了i×100条路径j到k的最短路径...原创 2018-07-31 18:02:28 · 541 阅读 · 3 评论 -
HDU3247-(AC自动机+spfa+状压dp)
题意:给你n个资源串和m个病毒串然后让你求最少需要多少个01字符才能做出不含病毒串并且含有所有的资源串的字符串题解:先跑一边AC自动机然后求出所有结点是资源串的结尾但是不是病毒串的结尾的结点,最后求这些结点到其他结点的最短距离,注意的是初始是空串所有0那个结点也要算进去,因为结点对应的数值很大但是满足条件的很少所以我们要给满足条件的结点重新编号,最后就是二维dp(第一维表示含有哪几个资源串,第原创 2017-10-01 15:44:47 · 464 阅读 · 0 评论 -
hdu2825-(AC自动机+状压DP)
题解:AC自动机,然后在自动机上跑一遍DP,第一维表示长度,第二维表示到达自动机上的哪一个结点,第三维用二进制表示有含有哪几个字符;然后转移方程就是dp[i+1][ret][k|v[ret]] = (dp[i+1][ret][k|v[ret]]+dp[i][j][k])%mod;有些dp[i][j][k]等于0就不用运算了#include#include#include#incl原创 2017-09-07 18:21:15 · 357 阅读 · 0 评论 -
POJ1015和uva323动态规划01背包扩展
题解:一开始以为这个符合最优子结构的动态规划,但是后来看了别人的题解发现不符合最优子结构,无法将所有的状态转移。因为可能我选了前面这个但是如果我选另外一个加上本身更优,这个时候选择没办法选择另外一个因为已经消失了,这个时候可以用01背包的思想做并且用一个vector数组记录一下路径,用数组第二维20*m是表示绝对差0两边表示绝对值差1.2.。。3.。。这样就可以把每一个状态转移过去了。#includ原创 2017-07-20 17:00:08 · 479 阅读 · 0 评论 -
LightOJ - 1422区间DP
题解:看了大牛的思路通俗易懂一下就明白了 dp[i][i]=1。就是这个舞会肯定要穿一件衣服dp[i]][j] 当a[i] == a[j] dp[i][j] = dp[i][j-1];之后枚举中间点k,注意(i#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;原创 2017-07-20 16:55:56 · 305 阅读 · 0 评论 -
poj3666-基础DP
题意:然你求如何使得这个序列单调不减或者单调不增然后代价比较小,因为数据比较弱只要求单调不增就可以了题解:dp[i][j]表示第i个位置改成第j小的数字代价花的最少然后记录一下i-1个位置改成第1-第j小的代价是多少就可以 dp[i][j] = pre[i-1][j]+abs(b[j]-a[i]); pre[i][j] = min(dp[i][j],pre[i][j-1]);#include<原创 2017-07-21 16:12:19 · 321 阅读 · 0 评论 -
hdu2476-区间DP
题解:我们可以先求把一个空白的字符串搞成跟b一样的串要至少要多少步 然后如果第i个a和b串的字符一样那么ans[i] = min(ans[i],ans[i-1]) 也就是是把1到第i变成和b串一样跟1到第i-1变成b串两者去变的最小值 然后ans[i] 要求如果ans[j]+dp[j+1][i]也就是两个分开变和一起变哪种方案最少最后ans[n]就是答案#include<iostream>#原创 2017-07-22 10:26:52 · 249 阅读 · 0 评论 -
codeforces838E-Convex Countour
题解:用i表示此时要用第i+1个点,用j表示要用n个点中的哪一个点,0表示此时点方向为顺时针0表示为逆时针,然后转移方程就是 放第i个点的时候取从上一个点走过来或者去相反旋转方向往后数i个点走过来的距离两者取最大值#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cstring>#原创 2017-08-08 21:48:02 · 11477 阅读 · 0 评论 -
hdu6125-(状态压缩+分组背包)
题解:因为小于根号500的质数有8个,我们可以用二进制表示为放入的这些数已经含有前面8个质数的哪几个然后,因为选择1-k个数后相乘起来没有平方因子,所以有任何能除以这前面8个质数的平方的都不可以,还有就是如果这个数把这8个质数能取余等0的都除后等于1的话那么这个数应该在自己这个数这一组,如果不能等于1的话应该再除以后剩下的那一组,为什么呢?因为除以后就剩下它的结果很显然只剩下一个质数了,那么这些数原创 2017-08-16 16:02:22 · 891 阅读 · 0 评论 -
HDU - 3652(数位DP+记忆化搜索)
题解:用pos表示第几位然后mod表示加上i后取余13后等于多少,have = 1表示上这上一位有1,2表示前面到达这里有13,0表示前面位数没有1也没有13,然后记录一下不是之前值得上限的时候dp[pos][mod][have].然后记忆化搜索一下即可#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>原创 2017-08-10 23:02:25 · 236 阅读 · 0 评论 -
hdu6035 Colorful Tree
题解:这个图构成了一树,单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和。反过来思考只需要求有多少条路径没有经过这种颜色即可。然后没有经过路线的条数就是以这个颜色为边界构成联通块能够组成的路径数目,路径数目就是联通块个数*(联通块个数-1)/2而这个点到下面结点的联通块个数就是这个颜色子节点为根的个数减去下面跟这个颜色一样的节点并且以这个节点为根树的节点个数总和 如何求下面代原创 2017-07-27 11:13:45 · 303 阅读 · 0 评论 -
hdu4352(状态压缩+LIS+数位dp)
题解:然后求l-r有多个个位数能组成最大上升序列有k 题解:一维表示位数,二维表示0-9上升序列有哪几个,三位表示前缀是不是0四位表示上升长度 然后转移方程如下: 当位数到达第pos为的时候,如果dp[pos][have][pre][k]如果不是这个上限的话就可以根据记忆化搜索记录一下#include<iostream>#include<cstring>#include<cstdio>#原创 2017-08-11 23:09:41 · 381 阅读 · 0 评论 -
HDU - 4734(数位DP)
题解:用一维表示位数二维表示到达该位数差x多少然后就是数位DP模板加上记忆化搜索,转移方程下面看一下代码就明白了#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;int dp[20][26000];int bit[20];int n,m,x;int dfs原创 2017-08-11 23:22:57 · 221 阅读 · 0 评论 -
HDU6082-度度熊与邪恶大魔王
题解:用完全背包预处理一下防御力为0-10生命为0-1000的最优情况然后就是直接加上去判断这个防御的时候有没有办法杀掉即可#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>using namespace std;typedef long long int ll;const int inf = 0x原创 2017-08-12 11:20:27 · 304 阅读 · 0 评论 -
hdu6155-Subsequence Count(线段树+矩阵+dp)
题解:dp[i][0],表示到第i个字符以0结尾的不同子串个数,dp[i][0]到第i个字符以1结尾的不同子串个数如果第i个字符是0的话dp[i][0] = dp[i-1][1]+dp[i-1][0]+1,dp[i][1] = dp[i-1][1]否则 dp[i][0] = dp[i-1][0],dp[i][1] = dp[i-1][1]+dp[i-1][0]+1然后可以推原创 2017-08-21 20:29:24 · 353 阅读 · 0 评论 -
hdu6161Big binary tree-(树形dp+空间优化)
题解:经过这个点最长路径可能是这个点的左右子树的最大值得和加上这个点的值或者是以这个点为根下面叶子节点爬上来的最大值加上max(它往真正的根爬途中经过的结点的值加上另外一棵子树)因为这个结点的值更新了只有影响到它上面那些节点的最大值所以只要把影响的那些节点的值记录一下,其他的结点的最大值根据它向下能向下几层向左取或者向右取就可以了。所以我们只要记录那些被影响的节点的值,其他的不记录到时候按照上原创 2017-08-24 20:05:21 · 339 阅读 · 0 评论 -
hdu6156-(数位dp)
题解:比赛时候没想到可以用数组存之前的放入的数组,结束后看了别人题解才明白过来,然后就是数位dp,第一维表示进制二维表示到达第几位三维表示回文数组的总长度,第四维表示这个数位是不是回文串然后数位dp模板套上去#include#include#include#includeusing namespace std;typedef long long int ll;ll dp[4原创 2017-08-22 10:55:58 · 322 阅读 · 0 评论 -
hdu2296-(AC自动机+DP)
题解:将字符串都放在AC自动机上然后看一下到达每个位置能增加多少权值,最后转移的时候跟根据权值大小,字典序大小更新一下即可.dp一维表示长度,二维表示到达哪个结点,一开始把所有的结点初始化成-表示不可能到达该结点dp[0][0]=0。转移方程看下面代码#include#include#include#include#includeusing namespace std;co原创 2017-09-07 18:28:55 · 494 阅读 · 0 评论 -
POJ1625-(AC自动机+DP+大数)
题解:跑一遍AC自动机,后直接在上面dp一维表示字符长度二维表示处于那个结点最后标记一下那些位置是危险结点不要转移过去即可,由于这题数据很大又没有取膜所以要用大数相加#include#include#include#include#includeusing namespace std;const int mod = 1e8;struct node{ int len;原创 2017-09-07 18:32:00 · 278 阅读 · 0 评论 -
牛客网暑期ACM多校训练营(第二场)-H(树形dp)
题意:让你找三条链权值总和最大题解:我们可以考虑一下在树上做dp用三维dp[u][i][j],u表示结点编号,i表示已经选取了i条链,j = 0表示没有选取该结点,j = 1表示选取了i条链里面包含u结点1条残链(即只有一头),j = 2表示选了i条链里面有一条包含i结点的完整链。现在我们开始考虑合并:如果不选择u结点那么我们就是选取所有儿子结点,链数总和为i的各种情况下最大值即可...原创 2018-07-27 18:19:26 · 229 阅读 · 0 评论