dp
文章平均质量分 64
dp
the best
自信即巅峰。
展开
-
Educational Codeforces Round 116 (Rated for Div. 2) E. Arena(dp)
传送门题意:对于一个数组 aaa ,假如当前有 cntcntcnt 个 aia_iai 大于 000,那么一回合后,所有大于000 的aia_iai 都会减去 cnt−1cnt-1cnt−1 ,假如经过几回合后,只剩下一个数大于000,则游戏结束,且存在胜者,反之则不存在胜者。求有多少数组aaa满足游戏结束时不存在胜者。题解:设dp[i][j]dp[i][j]dp[i][j]表示数组有 iii 个数,且所有数都是小于等于 jjj 的合法方案。1.1.1. 如果 i−1≥ji-1 \ge原创 2021-10-30 22:36:27 · 2685 阅读 · 0 评论 -
AtCoder Beginner Contest 217 F - Make Pair(区间dp)
草稿原创 2021-10-09 19:18:50 · 188 阅读 · 0 评论 -
Codeforces 1382D. Unmerge(思维+dp)
传送门题意:定义两个数组合并:每次比较开头的两个数,取小的数放入新数组,然后删除,重复上述过程,最后形成一个新数组。现在给出这个新数组,为全排列,求是否存在两个长度为nnn的数组合并后为这个新数组。题解:首先我们要发现,一个数 xxx 如果被放入新数组里,那么说明有一个数比他大,且这个数后面会被放到数组里。那么我们可以在新数组对 xxx 找到第一个大于它的数 yyy ,那么这两者之间的数就比 xxx 要小,那么这些数就不可能跟xxx 在不同的数组里,否则先进来的就不会是 xxx 。那么就可以知道原创 2021-09-18 21:48:59 · 157 阅读 · 0 评论 -
Luogu P1776 宝物筛选(单调队列优化dp)
传送门题面:题解:经典的多重背包问题,但是会tletletle设dp[i][j]dp[i][j]dp[i][j] 表示前 iii个物品,容量为 jjj 的最大价值,那么转移很好转移:dp[i][j]=max(dp[i−1][j−k×w[i]]+k×v[i])dp[i][j]=max(dp[i-1][j-k \times w[i]]+k \times v[i])dp[i][j]=max(dp[i−1][j−k×w[i]]+k×v[i])考虑如何优化:设 j=k1×w[i]+dj=k_1\ti原创 2021-08-24 19:35:06 · 170 阅读 · 0 评论 -
codeforces 1197D. Yet Another Subarray Problem(dp)
传送门题意:给出一个长度为nnn的数组aaa ,对于一段区间[l,r][l,r][l,r] ,其值为 (∑i=lrai)−k×⌈r−l+1m⌉(\sum\limits_{i=l}^{r} a_i)-k \times \lceil \frac{r-l+1}{m} \rceil(i=l∑rai)−k×⌈mr−l+1⌉求数组中最大的区间的值。(m≤10)(m\leq 10)(m≤10)题解:dpdpdp ,状态设计很妙。不难发现,每mmm个数,就会增加一个kkk ,又因为mmm很小,所以设计这样原创 2021-08-23 15:33:43 · 130 阅读 · 0 评论 -
codeforces1303E. Erase Subsequences(dp)
传送门题意:给出两个字符串sss,ppp ,有一种操作:取 sss 中的某一个子序列 ttt ,将其加入到 p′p'p′的末尾 ,并在原串中删除。最多只能进行两次操作,问p′p'p′ 能否等于ppp题解:枚举字符串ppp 的断点,前一部分的长度为len1len1len1 ,后一部分的长度为len2len2len2 。设 dp[i][j]dp[i][j]dp[i][j] 表示原串sss 匹配前半部分的iii个字符,后半部分的jjj 个字符,最少需要的长度。那么只需判断 dp[len1][len原创 2021-08-16 21:03:20 · 251 阅读 · 0 评论 -
Codeforces Round #595 (Div. 3) F. Maximum Weight Subset(树形dp)
传送门题意:给出一棵树,有nnn个节点,每个节点都有一个点权,选出点权和最大的点集,满足每个点之间的距离都大于kkk 。题解:容易想到树形dpdpdp。设dp[i][j]dp[i][j]dp[i][j] 表示以 iii为根的子树,选出的点中与 iii 最近的距离为 jjj 。1.1.1. 如果节点 iii 要选,那么dp[i][0]=a[i]+∑dp[son][k]dp[i][0]=a[i]+\sum dp[son][k]dp[i][0]=a[i]+∑dp[son][k]2.2.2. 如果节原创 2021-08-11 14:23:21 · 123 阅读 · 0 评论 -
Educational Codeforces Round 83 (Rated for Div. 2) E. Array Shrinking(区间dp)
传送门题意:给出一个数组aaa,若ai=ai+1a_i=a_{i+1}ai=ai+1 ,则两个数可以合并成ai+1a_i+1ai+1 然后形成新的数组。求最后数组最少能剩下多少元素。题解:区间dpdpdp ,设dp[i][j]dp[i][j]dp[i][j] 表示区间[i,j][i,j][i,j] 能剩下的最少的数,设a[i][j]a[i][j]a[i][j] 表示区间[i,j][i,j][i,j] 合并后剩下的数是什么。那么转移式为:dp[i][j]=min(dp[i][j],dp[i]原创 2021-08-04 19:59:14 · 86 阅读 · 0 评论 -
2021百度之星-鸽子(dp)
传送门题面思路:先考虑二维dp[i][j]dp[i][j]dp[i][j], 表示前 iii 个交换过后,到达点 jjj 的最小跳过操作次数。对于第 iii 对交换:dp[i][u[i]]=min(dp[i−1][u[i]]+1,dp[i−1][v[i]])dp[i][u[i]]=min(dp[i-1][u[i]]+1,dp[i-1][v[i]])dp[i][u[i]]=min(dp[i−1][u[i]]+1,dp[i−1][v[i]])dp[i][v[i]]=min(dp[i−1][v[i]原创 2021-07-31 20:15:25 · 321 阅读 · 0 评论 -
黑暗爆炸 - 3195 奇怪的道路(状压dp)
题解:设dp[i][j][s][c]dp[i][j][s][c]dp[i][j][s][c]表示处理到第iii个点,已经连了jjj条边,第i−ki-ki−k 到 iii 的点的连边数的奇偶状态二进制压缩为sss,当前处理到iii 与i−k+ci-k+ci−k+c 的连边。假如iii 与i−k+ci-k+ci−k+c 不连边,那么直接转移到状态dp[i][j][s][c+1]+=dp[i][j][s][c]dp[i][j][s][c+1]+=dp[i][j][s][c]dp[i][j][s][c+1]+.原创 2021-07-15 17:06:17 · 125 阅读 · 0 评论 -
Codeforces Round #728 (Div. 2) D. Tree Array(概率期望+dp+LCA)
题意:给出一个有nnn个节点的树,一开始所有节点都未被标记。随后标记规则如下:1.1.1. 一开始从nnn个节点中等概率的选择一个节点标记。2.2.2. 随后只能在有连向被标记的点的那些点中等概率的选择一个点然后标记。每标记一个点,则将其加入到数组末尾,求最后数组的逆序对的期望。题解:因为随后选择的点必须要与一个已经被标记的点相连,所以可以将第一个选择的点当做根节点,然后考虑暴力根节点和两个点(u,v)(u,v)(u,v) (v>u)(v>u)(v>u) ,求这两个点组成逆序原创 2021-07-14 10:36:48 · 162 阅读 · 0 评论 -
AtCoder Beginner Contest 207 E - Mod i(dp)
代码:#pragma GCC diagnostic error "-std=c++11"#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<queue>#include<map>#include<stack>#include<set>#inclu原创 2021-07-11 22:01:54 · 293 阅读 · 0 评论 -
AtCoder Beginner Contest 208 D-Shortest Path Queries 2(dp)
题意:给出一个nnn个点,mmm条边的有向带权图。定义f(s,t,k)f(s,t,k)f(s,t,k)表示起点为sss,终点为ttt,且途中只能经过111到kkk这kkk个点的最短路。求∑s=1n∑t=1n∑k=1nf(s,t,k)\sum\limits_{s=1}^{n}\sum\limits_{t=1}^{n}\sum\limits_{k=1}^{n}f(s,t,k)s=1∑nt=1∑nk=1∑nf(s,t,k)题解:一开始看到这题,没计算复杂度,直接想着暴力跑djdjdj求每个值,交上去原创 2021-07-11 21:28:42 · 273 阅读 · 0 评论 -
2020-2021 ICPC银川站B题 The Great Wall 题解(dp)
题意:给出一个长度为nnn的数组 aaa ,将数组分成 kkk 段,每段的价值为最大值减去最小值。数组的价值为每段价值之和。求k=1.2.3.4..nk=1.2.3.4..nk=1.2.3.4..n 时,数组的最大价值。题解:可以将每段价值转换成选择两个数相减,使得最后总和最大,那么最优必是最大值减去最小值,其实也可以看成选一个数乘上1,再选一个数乘上-1那么设dp[i][j][0]dp[i][j][0]dp[i][j][0] 表示前 iii 个数分成 jjj 段,且第jjj 段还未选择两个数,d原创 2021-05-22 21:16:35 · 3656 阅读 · 3 评论 -
Codeforces Global Round 14 E. Phoenix and Computers(dp)
代码:#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<queue>#include<map>#include<stack>#include<set>#include<ctime>#define iss ios::sync_with原创 2021-05-07 23:32:02 · 353 阅读 · 0 评论 -
CodeForces - 1517D D. Explorer Space(dp)
题意:给出一个n⋅mn \cdot mn⋅m 的网格和每条边的边权,求从每个点出发,走kkk步回到起点的最短路。题解:如果kkk为奇数,明显回不到起点,直接输出-1即可。因为要回到起点,所以出去的路和回来的路是一样的,如果是不一样的,那么选择其中前段k/2k/2k/2和后段k/2k/2k/2 中小的一段来回走,此时边权和比之前会更优,所以我们只要求出出去的k/2k/2k/2,那么回来只需乘2即可。那么怎么求出去的呢?设dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示从点(i原创 2021-05-07 20:09:45 · 212 阅读 · 0 评论 -
Codeforces Round #715 (Div. 2) C. The Sports Festival(区间dp)
题意:给出一个长度为n(n≤2000)n (n \leq 2000)n(n≤2000)的数组,定义 si=maxj=1ia[j]−minj=1ia[j]s_i=\max\limits_{j=1}^{i} a[j]- \min\limits_{j=1}^{i}a[j]si=j=1maxia[j]−j=1minia[j] , 重新排列数组,使得 ∑i=1ns[i]\sum\limits_{i=1}^{n} s[i]i=1∑ns[i] 最小。题解:尽量要让最大值和最小值晚出现,即要么把最大值放后原创 2021-04-17 14:55:25 · 286 阅读 · 0 评论 -
Codeforces Raif Round 1 (Div. 1 + Div. 2) F. Fruit Sequences(dp)
代码:#pragma GCC diagnostic error "-std=c++11"#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<queue>#include<map>#include<stack>#include<set>#inclu原创 2021-04-13 22:16:01 · 135 阅读 · 0 评论 -
2021 ICPC昆明 C.Cities(区间dp)
题意:给出一个长度为 nnn 的数组,一次操作可以选择一段连续且值都相同的区间,然后使其变成其他值,问最少需要多少次操作,才能使得数组的值全相等。数组中每个数最多出现151515次。题解:先对原数组连续相同的段压缩成111个, 这样保证相邻数不同。假设某一区间有mmm个数,如果这mmm个数都不相同,那么操作数最小是m−1m-1m−1 ,如果区间两端点的数相同,那么其实可以减少一次操作。考虑dp[i][j]dp[i][j]dp[i][j] ,表示区间(i,j)(i,j)(i,j) 能减少的最多操作数原创 2021-04-08 23:55:51 · 578 阅读 · 5 评论 -
Codeforces Round #693 (Div. 3) G. Moving to the Capital(最短路+dp)
题意:给出一个有向图,111为起点,did_idi 为起点到其他各个点的最短路,现在给出两种前进方式:1.1.1.如果 iii 与 jjj 相连,di<djd_i<d_jdi<dj ,那么点 iii 可以前往点 jjj 。2.2.2. 如果 iii 与 jjj 相连,di≥djd_i \geq d_jdi≥dj ,那么点 iii 可以前往点 jjj ,但这个方式只能进行一次。求从每个点出发,按照上述两种方式前进,能到达点的最小did_idi 是多少。题解:一开始必原创 2021-04-05 23:22:40 · 155 阅读 · 0 评论 -
CodeForces - 1499F Diameter Cuts(树形dp)
题意:给出一棵树,求有多少种删边的方案,使得删完后每个树的直径都不超过kkk 。题解:设dp[u][j]dp[u][j]dp[u][j] 表示以uuu 为根的子树,并且从uuu 开始的最长链为jjj 的方案数 。在dfsdfsdfs的过程中,求出每个子树的最长链。然后就是要当前的链长jjj和子树的链长 zzz ,可以推出状态转移方程:num[min(j,z+1)]+=dp[u][j]⋅dp[v][z]//子树v与u连接,转移的时候要判断j+z+1≤knum[min(j,z+1)]+=dp[u][j原创 2021-04-04 23:43:37 · 320 阅读 · 2 评论 -
Codeforces Round #677 (Div. 3) F. Zero Remainder Sum (dp)
题目链接题意:给出一个n⋅mn \cdot mn⋅m 的矩阵,可以在每行选择最多 m/2m/2m/2 个数,问选择的数的最大的和是多少,且能被kkk 整除。题解:设dp1[i][j][z]dp1[i][j][z]dp1[i][j][z] 表示第iii 行选 jjj 个数,模kkk 等于zzz 的最大值。那么就是背包问题。再设dp2[i][z]dp2[i][z]dp2[i][z] 表示第iii 行选任意个数,模kkk 等于zzz 的最大值。那么很容易由第一个转移而来。最后再设 dp3[i][z]原创 2021-03-25 21:49:52 · 110 阅读 · 0 评论 -
Codeforces Round #219 (Div. 1) C. Watching Fireworks is Fun(单调队列优化dp)
题目链接原创 2021-03-24 19:12:47 · 133 阅读 · 0 评论 -
牛客-HAOI2015]树上染色(树形dp)
题目链接题面:题解:设sz[i]sz[i]sz[i] 为以iii为根的子树的大小,设dp[i][j]dp[i][j]dp[i][j] 为以iii 为根的子树,选jjj 个点染成黑色的最大收益。接下来就是考虑怎么去计算出收益,因为不能暴力枚举黑点算距离,所以我们可以考虑每条边的贡献,贡献=(子树内黑点 ⋅\cdot⋅ 子树外黑点+子树内白点 ⋅\cdot⋅ 子树外白点) ⋅\cdot⋅ 边权转移方程就是类似于背包,枚举当前黑点数和子树的黑点数代码:#include<cstdio>原创 2021-03-18 21:29:44 · 260 阅读 · 0 评论 -
2021牛客寒假算法基础集训营6 E题-网格(dp)
题目链接题解:因为每个数可以在行方向选一个,列方向选一个,所以行和列其实是独立的,也就是说,我们可以对左右和上下分开算贡献。先考虑算左右的贡献,不难发现,每行的第一个数只能选右边的数,那我们可以设出dpdpdp数组,dp[j][1]dp[j][1]dp[j][1]表示某行第 jjj 个数选择左边的数,dp[j][0]dp[j][0]dp[j][0]表示选择右边,那么可以写出转移方程:dp[j][0]=max(dp[j−1][0],dp[j−1][1])dp[j][0]=max(dp[j-1][0]原创 2021-02-26 13:17:18 · 126 阅读 · 0 评论 -
Educational Codeforces Round 104 (Rated for Div. 2) E. Cheap Dinner(线段树优化dp)
题意:有n1n_1n1种主食,n2n_2n2种副食,n3n_3n3种饮料,n4n_4n4种甜点,有m1,m2,m3m_1,m_2,m_3m1,m2,m3对关系,m1m_1m1的每对关系代表一些主食与副食不能搭配,m2m_2m2代表一些副食与饮料不能搭配,m3m_3m3代表一些饮料和甜点不能搭配,每个食物都有价格,问怎么选才能使得价格最少,并且这444类都要有,输出最少的花费。题解:一开始想到了费用流,但是看到数据太大,就果断放弃了,后来想到用线段树维护,但是算错复杂度了,以为是个假原创 2021-02-24 16:46:24 · 160 阅读 · 0 评论 -
Codeforces Round #701 (Div. 2) F. Copy or Prefix Sum (map优化dp)
题意:给定一个数组b,求有多少个数组a,对于任意1≤i≤n1 \leq i\leq n1≤i≤n,满足a[i]=b[i]a[i]=b[i]a[i]=b[i]或∑j=1ia[j]=b[i]\sum\limits_{j=1}^{i}a[j]=b[i]j=1∑ia[j]=b[i] 。容易看出是dpdpdp,但难在怎么去优化 dpdpdp题解:设dp[i][j]dp[i][j]dp[i][j]表示前 i 项之和为 j 的方案数,那么就可以写出两种状态转移:dp[i][j]=dp[i−1][j−b[i]]原创 2021-02-16 20:44:29 · 149 阅读 · 0 评论 -
牛客-筛子游戏 (概率dp)
题目链接题解:原创 2021-02-11 14:13:10 · 1290 阅读 · 6 评论 -
牛客-黑白树(树形dp)
题目链接题面:题解:因为是向上染色,所以叶子节点肯定要选。接下来就是两种情况:1.节点 i 能不能被子树中的点染色,那么这个点肯定会被选。2.节点 i 能被子树中的某个点 j 染色,那么就出现了一个问题,i 这个点要不要选,因为我们可以先染 i 点再染 j 点,怎么去处理呢?我们可以将儿子节点附在父亲节点上,然后去更新父亲节点的最远距离:k[fa]=max(k[fa],k[son]-1)。 这样做可以将那些还没用到的点的剩余价值放在祖先节点,如果那些选择的点无法染到节点 i ,那么此时就可以用原创 2021-02-08 13:32:34 · 338 阅读 · 0 评论 -
牛客-旅游(树形dp)
题目链接题目:题解:这题其实是一个最大独立集的问题。先解释啥什么是最大独立集:一个点集,集合里面的点之间没有公共边,即每两个点之间没有边将他们连接起来,且集合中的点的数量最大。然后再来看这题,可以用dp来解决此问题,设dp[i][1]表示 点i在点集里,dp[i][0]表示 点 i 不在点集里。那么状态转移很容易可以写出来:dp[u][1]+=dp[v][0];dp[u][0]+=max(dp[v][1],dp[v][0]);#include<cstdio>#include&l原创 2021-02-05 20:28:46 · 165 阅读 · 0 评论 -
牛客-蓝魔法师(树形dp)
题目题解:设dp[i][j]表示以 i 为根的子树,选j个点保持连通的方案数。那么可以列出转移方程:for(int j=min(num[u],k);j>=1;j--)//枚举之前选了多少个点 for(int z=min(k,num[v]);z>=1;z--)//枚举当前子节点选了多少个点 dp[u][j+z]=dp[u][j+z]+dp[u][j]*dp[v][z];转移过程类似于背包,而且必须是从大枚举到小。还要注意的是,子节点这个子树也可能不选,那么状原创 2021-02-05 20:28:35 · 188 阅读 · 0 评论 -
AtCoder Beginner Contest 190 E - Magical Ornament(图论+状压dp)
题意:给出n种宝石,有m种关系,现在要在一排放置一些宝石,只有存在关系的宝石才能相邻,并且要求必须放置c数组里的宝石,问最少要放多少宝石?题解:这题比F题难是我没想到的。。。其实将题目转化一下就是:将所给的关系建边,然后在图中找到一条最短路径使得能包含所需所有点。首先我们需要求出必须放置的点之间两两的最短路径。因为k很小,所以我们可以进行k次bfs,求出两点间的最短距离。然后就是一个状压dp的问题了。设dp[i][j]表示状态 为 i 最后到达的点为 j 的最小路径。状态 i 变为二进制,第 i原创 2021-01-31 17:08:50 · 248 阅读 · 0 评论 -
Codeforces Round #691 (Div. 2) D. Glass Half Spilled
题意:给出n个水杯的容量和其已经包含的水量,有如下操作,选择两个杯子,将其中一个杯子中的x容量水转移到另一个杯子,但是会洒出x/2的水。现在求,对于1-n中每一个数字k,任意选择k个杯子,其水量之和最大是多少。题解:首先,对于被选的那k个杯子,它们一定不会倒水出去,所以我们先不考虑倒水,设dp[i][j][k]表示前i个水杯,选j个,其容量为k能够得到的最大水量。那么状态转移方程就是:dp[i][j][k]=max(dp[i-1][j][k],dp[i][j][k]);//不要第i个水杯dp[i原创 2021-01-30 13:18:15 · 169 阅读 · 0 评论