动态规划的题目

问题是动态规划?

代码

计数

题目题意思路代码
整数划分一个正整数 n n n 可以表示成若干个正整数之和,形如: n = n 1 + n 2 + ⋯ + n k n=n_1+n_2+\dots+n_k n=n1+n2++nk,其中 n 1 ≥ n 2 ≥ ⋯ ≥ n k ≥ 1 n_1≥n_2\ge\dots ≥n_k≥1 n1n2nk1。求划分方案数。 1 ≤ n ≤ 1 0 4 1\le n\le 10^4 1n104 f i , j f_{i,j} fi,j 表示只用 1 ∼ i 1\sim i 1i,凑出 j j j 的方案数,滚动压掉一维。80
AT232E H × W H\times W H×W的网格,你初始在 ( x 1 , y 1 ) (x1,y1) (x1,y1),做 K K K 次操作,使最终在 ( x 2 , y 2 ) (x2,y2) (x2,y2)。1.从 ( x , y ) (x,y) (x,y) 移动到 ( x ′ , y ) (x',y) (x,y),其中 1 ≤ x ′ ≤ H , x ′ ≠ x 1≤x'≤H,x'≠x 1xH,x=x 2.从 ( x , y ) (x,y) (x,y) 移动到 ( x , y ′ ) (x,y') (x,y),其中 1 ≤ y ′ ≤ W , y ′ ≠ y 1≤y'≤W,y'≠y 1yW,y=y。问有多少种可能的操作方案。 2 ≤ H , W ≤ 1 0 9 2\le H,W\le 10^9 2H,W109横向和纵向分开考虑。考虑横向走 m m m 步的方案,乘纵向走 k − m k-m km 步的方案,乘组合系数 C ( m , k ) C(m,k) C(m,k)67
[JRKSJ R5] 1-1 B给出一个长度为 n n n 且只包含 1 , − 1 1,-1 1,1 的序列,询问有多少个将 a a a 重排后的序列使得该序列的最大子段和最小化。称两个序列不同,当且仅当这两个序列有任意一个位置上的数不同。 1 ≤ n ≤ 1 0 4 1\le n\le 10^4 1n104先统计出 1 , − 1 1,-1 1,1 的数量,设有 a a a 1 1 1 b b b − 1 -1 1,若 a ≤ b a\le b ab,可以看作在 − 1 -1 1 中插入若干个 1 1 1,结果为 C b + 1 a C_{b+1}^a Cb+1a。若 a > b a>b a>b,易得最大子段和最小是 a − b a-b ab,可以考虑设计 f i , j f_{i,j} fi,j 表示前 i i i 个数和为 j j j 的方案数,考虑这个位置放置 1 , − 1 1,-1 1,1,方程为 f i , j = f i − 1 , j − 1 + f i − 1 , j + 1 f_{i,j}=f_{i-1,j-1}+f_{i-1,j+1} fi,j=fi1,j1+fi1,j+1,答案是 f n , a − b f_{n,a-b} fn,ab79
poem一个长度为 n n n 的正整数序列 a 1 , a 2 , a 3 , … , a n a_1,a_2,a_3,\dots,a_n a1,a2,a3,,an。在这个序列中找出 k k k 个数,将他们写成一个新的序列 b 1 , b 2 , b 3 , … , b k b_1,b_2,b_3,\dots,b_k b1,b2,b3,,bk(可以不按照顺序写),满足对所有的 1 ≤ i ≤ k 1\le i\le k 1ik,要么 b i 3 = b i + 1 \frac{b_i}{3}=b_{i+1} 3bi=bi+1(此时 b i b_i bi 必须是 3 的倍数),要么 2 b i = b i + 1 2b_i=b_{i+1} 2bi=bi+1。请你找出最大的符合要求的 k k k 1 ≤ n ≤ 1 0 5 , 1 ≤ a i ≤ 3 × 1 0 18 1\le n\le 10^5,1\le a_i\le 3\times 10^{18} 1n105,1ai3×1018​先证明序列不会形成环。关系有 2 2 2 种,即 b i 3 = b i + 1 \frac{b_i}{3}=b_{i+1} 3bi=bi+1 2 b i = b i + 1 2b_i=b_{i+1} 2bi=bi+1。则 b j = 2 p 2 q b i b_j=\frac{2^p}{2^q}b_i bj=2q2pbi( p , q p,q p,q 不同时 = 0 =0 =0 1 ≤ i < j ≤ n ) 1\leq i<j\leq n) 1i<jn),所以 b j ≠ b i b_j\neq b_i bj=bi。于是可以考虑用 dp f [ i ] [ j ] f[i][j] f[i][j] 表示长度为 i i i j j j 结尾的是否存在,考虑到 1 ≤ a i ≤ 3 × 1 0 18 1\leq a_i\leq3\times10^{18} 1ai3×1018,用哈希表。48
随机图给定 n n n 个点的无向图,每两个点有 p 1000 \frac{p}{1000} 1000p 的概率有边相连,求图中有大小超过 3 3 3 的连通块的概率。 2 ≤ n ≤ 100 , 0 ≤ p ≤ 1000 2\le n\le 100,0\le p\le 1000 2n100,0p1000正难则反。超过 3 3 3 的连通块概率 = 1 − =1- =1 不超过 3 3 3 的连通块概率令 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k] 表示前 i i i 个点有 j j j 个大小为 2 2 2 的连通块, k k k 个大小为 3 3 3 的连通块, l = i − 2 j − 3 k l=i-2j-3k l=i2j3k 个孤立点的概率。1.这个点是孤立的,不跟前面 i i i 个点有关联,乘 ( 1 − p ) i (1-p)^i (1p)i。2.这个点与之前孤立点构成一个大小为 2 2 2 的连通块,转移到 f [ i + 1 ] [ j + 1 ] [ k ] f[i+1][j+1][k] f[i+1][j+1][k],乘 l p ( 1 − p ) i − 1 lp(1-p)^{i-1} lp(1p)i1。3.这个点与两个孤立点构成大小为 3 3 3 的连通块,转移到 f [ i + 1 ] [ j ] [ k + 1 ] f[i+1][j][k+1] f[i+1][j][k+1],乘 C 2 l ( 1 − p ) i − 2 p 2 C^l_2(1-p)^{i-2}p^2 C2l(1p)i2p2。4.这个点与一个大小为 2 2 2 的连通块构成大小为 3 3 3 的连通块( 2 2 2 边),转移到 f [ i + 1 ] [ j − 1 ] [ k + 1 ] f[i+1][j-1][k+1] f[i+1][j1][k+1],任选 2 2 2 点之一连边,乘 2 j ( 1 − p ) i − 1 p 2j(1-p)^{i-1}p 2j(1p)i1p。5.这个点与一个大小为 2 2 2 的连通块构成大小为 3 3 3 的连通块( 3 3 3 边),转移到 f [ i + 1 ] [ j − 1 ] [ k + 1 ] f[i+1][j-1][k+1] f[i+1][j1][k+1],选 2 2 2 点都连边,乘 j ( 1 − p ) i − 1 p 2 j(1-p)^{i-1}p^2 j(1p)i1p2115
Star MST有一个 n n n 个点的无向完全图,边权 e ∈ [ 1 , k ] e∈[1,k] e[1,k],已知该图的最小生成树的权值与所有与 1 1 1 号点相连的边的边权和相同,求有多少种构图方式,答案对 998244353 998244353 998244353 取模, 2 ≤ n ≤ 250 , 1 ≤ k ≤ 250 2\leq n \leq 250 , 1 \leq k \leq 250 2n250,1k250 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示前 i i i 个数,所有点与 1 1 1 连边的最大值为 j j j 的方案数,从小到大枚举边权和前缀和优化即可。考虑前面有 t t t 个点的距离 < j <j <j,那么我们首先要从剩下的点中选取,然后集合两两连边,发现只要交换一下顺序,就能省去前缀和。116

树形

题目题意思路代码
AT220F Distance Sums 2给定一棵 n n n 个点的树,求出每个点到其他所有点的距离和。 2 ≤ n ≤ 2 × 1 0 5 2\le n\le2\times10^5 2n2×105假设我们已经知道了点 x x x 的答案,便可求与它有连边的点 v v v 的答案,从 x x x 移动到 v v v v v v 的子树内的点的距离都减小了 1 1 1,而其余的节点的距离都增大了 1 1 1,如果 a n s i ans_i ansi 表示 i i i 号节点的答案,表示 s i s_i si 表示子树大小,则有 a n s v = a n s x + n − s x − s x ans_v=ans_x+n-s_x-s_x ansv=ansx+nsxsx。可以从 1 1 1 出发,求出 1 1 1 的答案,然后从 1 1 1 出发再做一次 dfs,求出相邻的节点。1

状压

题目题意思路代码
国王 n 2 n^2 n2 的棋盘上放 k k k 个国王,国王可攻击相邻的 8 8 8 个格子,求使它们无法互相攻击的方案总数。 1 ≤ n ≤ 10 , 0 ≤ k ≤ n 2 1\le n\le10,0\le k\le n^2 1n10,0kn2把一行的摆放方式用 2 2 2 进制表示,用位运算判断八个方向的国王是否存在攻击。左右用 i&(i>>1),上下用 x&yx&(y>>1)y&(x>>1)判斜对角。初始状态 dp[0][1][0]=1表示前 0 0 0 行状态为 1 1 1 并且放了 0 0 0 个国王。注意此题需要 long long2
AT199E Permutation对于 m m m 个限制,满足 a 1 , a 2 , a 3 , ⋯   , a x i a_1,a_2,a_3,\cdots,a_{x_i} a1,a2,a3,,axi 中至多有 z i z_i zi 个数 ≤ y i \le y_i yi。求满足条件的 n n n 的排列数。 0 ≤ m ≤ 100 , 2 ≤ n ≤ 18 0\le m\le100,2\le n\le 18 0m100,2n18因为 n n n 很小,考虑状压。 f [ i ] f[i] f[i] 表示填数状态为 i i i 时的合法方案数,第 j j j 位二进制为 1 1 1 表示数字 j j j 已经被填过。3
AT232F给定两个长度为 n n n 的序列 a a a b b b,可以进行以下两种操作:1.对 a i ± 1 ( 1 ≤ i ≤ n ) ai±1(1≤i≤n) ai±1(1in),代价为 x x x。2.交换 a i ai ai a i + 1 ( 1 ≤ i < n ) a_{i+1}(1≤i<n) ai+1(1i<n),代价为 y y y。问最少的代价使得 a a a 序列变成 b b b 序列。 2 ≤ N ≤ 18 , 1 ≤ X ≤ 1 0 8 , 1 ≤ Y ≤ 1 0 16 , 1 ≤ A i , B i ≤ 1 0 8 2≤N≤18,1≤X≤10^8,1≤Y≤10^{16},1≤Ai,Bi≤10^8 2N18,1X108,1Y1016,1Ai,Bi108两种操作分开考虑,先交换出 P 1 , P 2 , P 3 , … , P n P_1,P_2,P_3,\dots,P_n P1,P2,P3,,Pn 的排列,再统计第 1 1 1 个答案,令 i n v ( P ) inv(P) inv(P) 为排列 P P P 的逆序对,则答案为: ∑ i = 1 n x × a b s ( a P i − b i ) + i n v ( P ) × y \sum_{i=1}^n x\times abs(a_{P_i}-b_i)+inv(P)\times y i=1nx×abs(aPibi)+inv(P)×y。关于逆序对的贡献,我们可以单独拿出 i i i 来看,也就是在 P 1 , P 2 , P 3 , … , P i − 1 P_1,P_2,P_3,\dots,P_{i-1} P1,P2,P3,,Pi1 中有多少个比 P i P_i Pi 大。68
[SCOI2007]排列给一个数字串 s s s 和正整数 d d d, 统计 s s s 有多少种不同的排列能被 d d d 整除(可以有前导 0 0 0)。 f [ i ] [ j ] f[i][j] f[i][j] 表示集合 i i i,余数为 j j j 的答案。考虑每次再尾部添加一个数之后的情况,易得转移为 f [ i ∣ 1 < < k ] [ ( j ∗ 10 + s [ k ] − 48 ) m o d    d ] + = f [ i ] [ j ] f[i|1<<k][(j*10+s[k]-48)\mod d]+=f[i][j] f[i∣1<<k][(j10+s[k]48)modd]+=f[i][j]-12
Kefa and Dishes给定 n n n 个数,你要选择 m m m 个数,如果两个数是相邻被选,那么他们会产生一个额外贡献。求所选数之和与额外贡献之和相加的最大值 f [ i ] [ j ] f[i][j] f[i][j] 表示集合为 i i i,最后选 j j j。考虑再选一个数,转移为 f [ s ∣ ( 1 < < j ) ] [ j ] = max ⁡ ( f [ s ∣ ( 1 < < j ) ] [ j ] , f [ s ] [ i ] + a [ j ] + c [ i ] [ j ] ) f[s|(1<<j)][j]=\max(f[s|(1<<j)][j],f[s][i]+a[j]+c[i][j]) f[s(1<<j)][j]=max(f[s(1<<j)][j],f[s][i]+a[j]+c[i][j])-13
Captains Mode n n n 张卡,每张卡有一个权值。现在有 m m m 个操作,每个操作可能是两人之一,操作共两类:1.选择卡或不选。2.禁卡使其不能被选或不禁。考虑如果可以选那么这个人必然会选,且选权值最大的,那么我们发现其实只会用到 m m m 张牌,而且不禁牌与禁最差牌等价(因为最差牌必然不会被选)。所以用 f [ i ] f[i] f[i] 表示已选了集合 i i i 后还能产生的答案。答案是 f [ 0 ] f[0] f[0]-14
[POI2004]PRZ n n n 个队员过桥,桥有最大载重 w w w。每个队员有过桥速度和体重。问所有队员过桥最短用时这里需要用到枚举子集的方法,时间复杂度 O ( 3 n ) O(3^n) O(3n),预处理过桥花费和体重,用 d p i dp_i dpi 表示集合 i i i 的答案,考虑需要满足重量限制,然后转移是 d p [ S ] = m i n ( d p [ S ] , d p [ S ⊕ T ] + c o s t [ T ] ) dp[S]=min(dp[S],dp[S⊕T]+cost[T]) dp[S]=min(dp[S],dp[ST]+cost[T])-15
A Simple Task求简单无向图的环数 d p [ S ] [ u ] dp[S][u] dp[S][u] 表示状态 S S S 中的最小标号出发,到达 u u u 的链数量。 转移就是枚举 u u u 的下一个点 v v v d p [ S ∣ ( 1 < < v ) ] [ v ] + = d p [ S ] [ u ] dp[S | (1 << v)][v] += dp[S][u] dp[S(1<<v)][v]+=dp[S][u],满足相连,答案 ÷ 2 \div 2 ÷2,因为有顺时针和逆时针-16
最少连通块数给定一张无向图,去掉任意条边后,使得每个子图都是团。 f S f_S fS 表示集合为 S S S 的答案,枚举子集 T T T,且其为团, f [ S ] = min ⁡ ( f [ S ] , f [ S − T ] + 1 ) f[S]=\min(f[S],f[S-T]+1) f[S]=min(f[S],f[ST]+1)-22

区间

题目题意思路代码
CF607B给定长度为 n n n 的数组 c c c,每次可以删除一个回文子段,求最少几次可以删完。 1 ≤ c i ≤ n ≤ 100 1\le c_i\le n \le 100 1cin100 f [ i ] [ j ] f[i][j] f[i][j] 表示子串 i i i j j j 这部分的删除次数。初始 f [ i ] [ i ] = 1 f[i][i]=1 f[i][i]=1。接着有两种状态转移方程:如果满足 a i = a j a_i=a_j ai=aj,即两边的颜色相同,如果满足 l e n > 2 len>2 len>2,即中间还有回文串被消除,可以带上去,即 f [ i ] [ j ] = f [ i + 1 ] [ j − 1 ] f[i][j]=f[i+1][j-1] f[i][j]=f[i+1][j1] 如果 l e n = 2 len=2 len=2,则 f [ i ] [ j ] = 1 f[i][j]=1 f[i][j]=1 还有一种情况,枚举 k k k,然后 f [ i ] [ j ] = min ⁡ ( f [ i ] [ k ] + f [ k + 1 ] [ j ] , f [ i ] [ j ] ) f[i][j]=\min(f[i][k]+f[k+1][j],f[i][j]) f[i][j]=min(f[i][k]+f[k+1][j],f[i][j]),即把当前状态劈开的情况。4
狼群 n n n 头狼围成一圈,每消灭一头狼会受到这头狼的攻击力。基础攻击力均为 1 1 1,第 i i i 头狼对左右两头狼有 a i a_i ai 的攻击加成,如果剩余两头狼,加成只有 1 1 1 次,求消灭所有狼受到的伤害总和最小值。 1 ≤ n ≤ 500 , 1 ≤ a i ≤ 1 0 5 1\le n\le500,1\le a_i\le 10^5 1n500,1ai105首先特判,只有 1 1 1 匹狼和 2 2 2 匹狼,为 1 1 1 直接输出 1 1 1,为 2 2 2 输出 2 + max ⁡ ( a 1 , a 2 ) 2+\max(a_1,a_2) 2+max(a1,a2),然后化环为链,把原数组备份一遍。接着 a 0 = a 2 n , a 2 n + 1 = a 1 a_0=a_{2n},a_{2n+1}=a_1 a0=a2n,a2n+1=a1 调边界。然后把长度为 1 1 1 的区间先弄好 f [ i ] [ j ] = min ⁡ ( f [ i ] [ j ] , f [ i ] [ k − 1 ] + f [ k + 1 ] [ j ] + v a l ) f[i][j]=\min(f[i][j],f[i][k-1]+f[k+1][j]+val) f[i][j]=min(f[i][j],f[i][k1]+f[k+1][j]+val) 还有不合法区间设为 0 0 0。接下来,外层枚举区间的大小,然后枚举左端点,如果右端点是合法的,就分情况考虑:1.当前区间长度为 n n n,则只剩 1 1 1 匹狼,伤害为 v a l = 1 val=1 val=1;2.当前区间长度为 n − 1 n-1 n1,则只剩 2 2 2 匹狼,伤害即加成只有一次 v a l = 1 + a i − 1 val=1+a_{i-1} val=1+ai1;3.否则加成多次 v a l = a i − 1 + a j + 1 + 1 val=a_{i-1}+a_{j+1}+1 val=ai1+aj+1+1,然后枚举一个 k k k,表示当前区间最后杀死的狼,方程 f [ i ] [ j ] = min ⁡ ( f [ i ] [ j ] , f [ i ] [ k − 1 ] + f [ k + 1 ] [ j ] + v a l ) f[i][j]=\min(f[i][j],f[i][k-1]+f[k+1][j]+val) f[i][j]=min(f[i][j],f[i][k1]+f[k+1][j]+val)5
Alien 的粉刷给定一个长度为 n n n 的目标颜色序列,现在有一个长度为 n n n 的没有任何颜色的序列,每次可以选择任意一段染色,颜色会覆盖,问染成目标颜色序列需要多少次。 1 ≤ n ≤ 50 1\le n\le 50 1n50 f [ i ] [ j ] f[i][j] f[i][j] 表示 i i i j j j 的最少次数,如果 c i = c j c_i=c_j ci=cj f [ i ] [ j ] = f [ i + 1 ] [ j ] f[i][j]=f[i+1][j] f[i][j]=f[i+1][j],否则 f [ i ] [ j ] = min ⁡ ( f [ i ] [ k ] + f [ k + 1 ] [ j ] ) f[i][j]=\min(f[i][k]+f[k+1][j]) f[i][j]=min(f[i][k]+f[k+1][j])69

背包

题目题意思路代码
AT220D长度为 n n n 的数组,在只剩一个元素之前,你必须进行以下两种操作之一。1.删掉当前最左边两个数 x , y x,y x,y,添加 ( x + y ) m o d    10 (x+y)\mod 10 (x+y)mod10 到数组左侧。2.删掉当前最左边两个数 x , y x,y x,y,添加 x × y m o d    10 x\times y\mod 10 x×ymod10 到数组左侧。问在所有合法方案中,最终剩下的值为 0 , 1 , 2 , ⋯   , 9 0,1,2,\cdots,9 0,1,2,,9 的情况各有多少种,对 998244353 998244353 998244353 取模。 2 ≤ n ≤ 1 0 5 2\le n\le10^5 2n105 f [ i ] [ j ] f[i][j] f[i][j] 表示前 i i i 个数,结果为 j j j 的情况下的方案数。显然 f [ 1 ] [ a 1 ] = 1 f[1][a_1]=1 f[1][a1]=1 + : f [ i + 1 ] [ ( j + a [ i + 1 ] ) m o d    10 ] + = f [ i ] [ j ] +:f[i+1][(j+a[i+1])\mod 10]+=f[i][j] +:f[i+1][(j+a[i+1])mod10]+=f[i][j] × : f [ i + 1 ] [ j × a [ i + 1 ] m o d    10 ] + = f [ i ] [ j ] \times:f[i+1][j\times a[i+1]\mod 10]+=f[i][j] ×:f[i+1][j×a[i+1]mod10]+=f[i][j]6
货币系统给定长度为 n n n 的数组 a a a,自己拟定一个长度为 m m m 的数组 b b b,使得由 a a a 中的数能表示出的数 b b b 也行,求 m m m 的最小值。 1 ≤ n ≤ 100 1\le n\le100 1n100这题表面上是问是否能简化货币系统,实际上是问这些数字最少需要多少数字才能全部组合出来(因为本质上 123 1 2 3 123 可以简化为 12 1 2 12,因为可以通过小的组合成大的)。很容易联想到完全背包。 f [ i ] f[i] f[i] 表示 i i i 是否能被表示出来,在完全背包内部,加上判断这个数字的位置是否被标记过,标记过跳过就好了。7
平分数字给定 n n n 个数,取走若干个数,使得这些数分为两组后组内数之和相等,求每组可能的数之和的最大值。 1 ≤ n ≤ 500 1\le n\le 500 1n500,所有数之和 ≤ 2 × 1 0 5 \le 2\times 10^5 2×105 f [ i ] [ j ] f[i][j] f[i][j] 表示前 i i i 个数中差值为 j j j 的取得数字和较小的人数字和。如果当前方案可行,则有三种状态转移:1.直接转移过来,这个数字谁也不给。即 f[i][j]=max(f[i][j],f[i-1][j])2.数字给和小的人,由于给了之后小的可能变成大的,所以把两个数都算出来,然后求出新差值,int x=f[i-1][j];int y=x+j;int d=abs(x+a[i]-y);f[i][d]=max(f[i][d],min(x+a[i],y));3.数字给和大的人,然后求出新差值d=abs(x-(y+a[i])),f[i][d]=max(f[i][d],min(x,y+a[i]))8
AT195E Lucky 7 Battle长度为 n n n 的字符串 S S S 只包含数字,字符串 X X X 只包含 A A A T T T,字符串 T T T 是空串。当 X i X_i Xi A A A 时,Aoki 操作,否则 Takahashi 操作。每次操作可将 0 0 0 S i S_i Si 放在 T T T 末尾。如果 T T T 7 7 7 的倍数则 Takahashi \text{Takahashi} Takahashi 获胜,否则 Aoki \text{Aoki} Aoki 获胜。若两人都是用最优策略,谁会获胜。 1 ≤ n ≤ 2 × 1 0 5 1\le n\le 2\times 10^5 1n2×105逆向递推,首先 n n n 次余数为 0 0 0 肯定是先手必胜,标为 1 1 1,然后遍历每次, 7 7 7 种余数,如果当前操作人是希望先手必胜,那么只要 j ∗ 10 + 0 / n u m j*10+0/num j10+0/num一者满足,就能先手必胜,如果不希望的,那么他肯定会选择不让先手必胜的策略,除非两者都满足先手必胜。26
Magic Gems很多魔法宝石,每颗魔法宝石可以分解成 m m m 颗普通宝石,魔法宝石和普通宝石都占据 1 1 1 体积,普通宝石不能再分解。求有多少分解方案可占据 n n n 的空间。转移, f i = f i − 1 + f i − m f_i=f_{i-1}+f_{i-m} fi=fi1+fim,分别为普通和魔法宝石的转移。然后构造大小为 m m m 的矩阵即可。-20

记忆化搜索

题目题意思路代码
乌龟棋给定 n n n 个格子和 m m m 张卡,第 i i i 格的分值为 a i a_i ai,初始在第 1 1 1 格。每种卡片可以走 1 ∼ 4 1\sim 4 14 格,可以任意调整卡片的使用顺序,求从 1 1 1 n n n 所经过的格子分值和。 1 ≤ n ≤ 350 , 1 ≤ m ≤ 120 , 0 ≤ a i ≤ 100 1\le n\le350,1\le m\le120,0\le a_i\le100 1n350,1m120,0ai100状态的表示 f [ i ] [ j ] [ k ] [ l ] f[i][j][k][l] f[i][j][k][l] 表示有 i i i 张前进 1 1 1 格的卡, j j j 张前进 2 2 2 格的卡, k k k 张前进 3 3 3 格的卡, l l l 张前进 4 4 4 格的卡。dfs里面 f [ i ] [ j ] [ k ] [ l ] f[i][j][k][l] f[i][j][k][l] 可以取 dfs(i-1,j,k,l),dfs(i,j-1,k,l),dfs(i,j,k-1,l),dfs(i,j,k,l-1) max ⁡ \max max9
滑雪有一张 R × C R\times C R×C 的地图,每个点 ( i , j ) (i,j) (i,j) 都有一个高度 h i h_i hi,定义若两个格子相邻且高度不等,则较高的格子可以到达较低的格子。求从任意一点出发可到的点数的最大值。 1 ≤ R , C ≤ 100 1\le R,C\le100 1R,C100用记忆化搜索写十分方便,每次记录结果,一个点的最大值应该是它的相邻点的最大值 + 1 +1 +1。注意需要先搜相邻点再求最大值。10

数字三角形

题目题意思路代码
2000方格取数给定一个 n 2 n^2 n2 的网格,每个格子都有一个权值,求从左上角到右下角走两次能取到的最大数字和,每次只能向下或向右走,一个格子里的数只能被取一次。 1 ≤ n ≤ 9 1\le n\le9 1n9根据次对角线的定义,一条线上行列坐标和相等,所以我们知道 x x x 坐标,就能推出 y y y 坐标,于是状态的表示是: 表示行列坐标和为 k k k ,第一次到达 x 1 x_1 x1 坐标,第二次到达 x 2 x_2 x2 坐标的最大值。 于是有 4 4 4 种状态转移方程,分别是第 1 1 1 个坐标取值从上面或左边取,第 2 2 2 个坐标同理,定义 v a l u e value value 表示取到的数,即若 x 1 = x 2 x_1=x_2 x1=x2 则贡献一次,否则贡献两次。于是有: f [ k ] [ x 1 ] [ x 2 ] = max ⁡ ( f [ k ] [ x 1 ] [ x 2 ] , f [ k − 1 ] [ x 1 − 1 ] [ x 2 − 1 ] + v a l u e ) , f [ k ] [ x 1 ] [ x 2 ] = max ⁡ ( f [ k ] [ x 1 ] [ x 2 ] , f [ k − 1 ] [ x 1 − 1 ] [ x 2 ] + v a l u e ) , f [ k ] [ x 1 ] [ x 2 ] = max ⁡ ( f [ k ] [ x 1 ] [ x 2 ] , f [ k − 1 ] [ x 1 ] [ x 2 − 1 ] + v a l u e ) , f [ k ] [ x 1 ] [ x 2 ] = m a x ( f [ k ] [ x 1 ] [ x 2 ] , f [ k − 1 ] [ x 1 ] [ x 2 ] + v a l u e ) f[k][x1][x2]=\max(f[k][x1][x2],f[k-1][x1-1][x2-1]+value),f[k][x1][x2]=\max(f[k][x1][x2],f[k-1][x1-1][x2]+value),f[k][x1][x2]=\max(f[k][x1][x2],f[k-1][x1][x2-1]+value),f[k][x1][x2]=max(f[k][x1][x2],f[k-1][x1][x2]+value) f[k][x1][x2]=max(f[k][x1][x2],f[k1][x11][x21]+value),f[k][x1][x2]=max(f[k][x1][x2],f[k1][x11][x2]+value),f[k][x1][x2]=max(f[k][x1][x2],f[k1][x1][x21]+value),f[k][x1][x2]=max(f[k][x1][x2],f[k1][x1][x2]+value),当然需要满足边界条件。11
2020方格取数给定一个 n × m n\times m n×m 的网格,每个格子都有一个权值,求从左上角到右下角走两次能取到的最大数字和,每次只能向下或向右或向上走。 1 ≤ n , m ≤ 1 0 3 1\le n,m\le10^3 1n,m103第一列是肯定可以推出的,而且是唯一的(因为不能往左走,所以不能先向前再向下然后向左到达),然后可以推第二列,发现有从上往下走和从下往上走,从上往下走的话,发现第一行是只有左边能走过来的,于是接下来的每行都是上一行到达的最大值和从左边过来的,当然从下往上走和刚才的很类似,先推最后一行,这里就不作太详细的分析了,然后推完了,把两种情况中较大的一个放到数组里,接着一直推,推出最后一行。注意我们这里是一列列推的,所以循环外层是代表列,内层是行,不要在计算时把两者搞反了,如下,三个 max ⁡ \max max 那里 j j j 代表的是行, i i i 代表的是列。12
AT233G给定一张 N × N N×N N×N 网格,上面有一些障碍物。每次可以选择 D × D ( 1 ≤ D ≤ N ) D×D(1\le D\le N) D×D(1DN) 的全部是障碍物的区域花费 D D D 消除区域内所有障碍物。问消除所有障碍物的最小花费。 1 ≤ N ≤ 50 1\le N\le 50 1N50 d p [ x 1 ] [ y 1 ] [ x 2 ] [ y 2 ] dp[x1][y1][x2][y2] dp[x1][y1][x2][y2] 表示这个子矩阵的最小花费。有 3 3 3 种转移:直接清除,把 x x x 分为两部分清除,把 y y y 分为两部分清除。70

状态机

题目题意思路代码
摆渡车 n n n 名学生,以及每个同学到达车站的时间 t i t_i ti,车往返一次需要 m m m 的时间,求所有同学等车的时间总和的最小值。 n ≤ 500 , m ≤ 100 , 0 ≤ t i ≤ 4 × 1 0 6 n\le 500,m\le 100,0\le t_i\le 4\times 10^6 n500,m100,0ti4×106首先排序 t i t_i ti 数组。 f [ i ] [ j ] f[i][j] f[i][j] 表示前 i i i 个人已经上车后到达第 i i i 个人的等待时间。每个同学最坏的情况是来之前刚好走,每个人的等待时间不会超过 2 m 2m 2m,所以 f [ i ] [ j ] = min ⁡ ( f [ i ] [ j ] , f [ i − 1 ] [ k ] + j ) f[i][j]=\min(f[i][j],f[i-1][k]+j) f[i][j]=min(f[i][j],f[i1][k]+j) 第一个条件表示第 i i i 个同学和第 i − 1 i-1 i1 同学做同一班车,然后时间计算等待时间计算是 f [ i − 1 ] [ k ] + j f[i-1][k]+j f[i1][k]+j ,第二个条件是第 i i i 个同学新开一班车,条件相同。13
纪念品 T T T n n n 个物品,每个物品当天有一个价格,每天可以买入/卖出物品,初始有 m m m 枚金币,求最终最多可以得到多少钱。 T , n ≤ 100 , m ≤ 1 0 3 T,n\le100,m\le 10^3 T,n100,m103 1 ≤ 1\le 1 价格 $\le 10^4,任意时刻,金币数不可能超过 1 0 4 10^4 104 f [ i ] f[i] f[i] 表示 i i i 元可以得到的利润。利润为卖价成本之差。我们把当前天数的价格当成成本,后一天当成卖价。状态转移方程 f [ j ] = max ⁡ ( f [ j ] , f [ j − p [ i ] [ k ] ] + p [ i + 1 ] [ k ] − p [ i ] [ k ] ) , f [ j ] = max ⁡ ( f [ j ] , f [ j − p [ i ] [ k ] ] + p [ i + 1 ] [ k ] − p [ i ] [ k ] ) f[j]=\max(f[j],f[j−p[i][k]]+p[i+1][k]−p[i][k]),f[j]=\max(f[j],f[j−p[i][k]]+p[i+1][k]−p[i][k]) f[j]=max(f[j],f[jp[i][k]]+p[i+1][k]p[i][k]),f[j]=max(f[j],f[jp[i][k]]+p[i+1][k]p[i][k]) f [ j − p [ i ] [ k ] ] f[j−p[i][k]] f[jp[i][k]] 表示买这个物品还剩的利润,买这件物品的利润是 p [ i + 1 ] [ k ] − p [ i ] [ k ] p[i+1][k]−p[i][k] p[i+1][k]p[i][k]14
选择数字/修剪草坪给定 n n n 个非负整数。可以选择其中若干个数,但不能有超过 k k k 个连续的数字被选择。求选出的数的和的最大值。 1 ≤ k ≤ n ≤ 1 0 5 1 \le k\le n\le 10^5 1kn105 0 ≤ 0\le 0 所有数字 ≤ 1 0 9 \le 10^9 109 f i f_i fi 表示前 i i i 头奶牛的最大收益。要使得不能出现超过 k k k 个连续的数,所以要使 [ i − k , i ] [i-k,i] [ik,i] 的范围内的 1 1 1 头奶牛不工作,设这头奶牛是 j j j,预处理效率前缀和 s i s_i si ,则 f i = max ⁡ ( f j − 1 + s i − s j ) ( i − k ≤ j ≤ i ) f_i=\max(f_{j-1}+s_i-s_j)(i-k\le j\le i) fi=max(fj1+sisj)(ikji),考虑 s i s_i si 是定值,将其提取,可得 f i = max ⁡ ( f j − 1 − s j ) + s i f_i=\max(f_{j-1}-s_j)+s_i fi=max(fj1sj)+si ,刚好是长度为 k k k 的滑动窗口,直接用单调队列优化做到 O ( n ) O(n) O(n)。需要注意的是 j j j 可以取到 i i i,所以把 i i i 入队后再计算(否则会出现 P2627 能过,P2034 不能过的情况)。15

单调队列优化

题目题意思路代码
选择数字/修剪草坪给定 n n n 个非负整数。可以选择其中若干个数,但不能有超过 k k k 个连续的数字被选择。求选出的数的和的最大值。 1 ≤ k ≤ n ≤ 1 0 5 1 \le k\le n\le 10^5 1kn105 0 ≤ 0\le 0 所有数字 ≤ 1 0 9 \le 10^9 109 f i f_i fi 表示前 i i i 头奶牛的最大收益。要使得不能出现超过 k k k 个连续的数,所以要使 [ i − k , i ] [i-k,i] [ik,i] 的范围内的 1 1 1 头奶牛不工作,设这头奶牛是 j j j,预处理效率前缀和 s i s_i si ,则 f i = max ⁡ ( f j − 1 + s i − s j ) ( i − k ≤ j ≤ i ) f_i=\max(f_{j-1}+s_i-s_j)(i-k\le j\le i) fi=max(fj1+sisj)(ikji),考虑 s i s_i si 是定值,将其提取,可得 f i = max ⁡ ( f j − 1 − s j ) + s i f_i=\max(f_{j-1}-s_j)+s_i fi=max(fj1sj)+si ,刚好是长度为 k k k 的滑动窗口,直接用单调队列优化做到 O ( n ) O(n) O(n)。需要注意的是 j j j 可以取到 i i i,所以把 i i i 入队后再计算(否则会出现 P2627 能过,P2034 不能过的情况)。15
Mice and Holes n n n 个老鼠, m m m 个洞,告诉你他们的一维坐标和 m m m 个洞的容量限制,问最小总距离。 1 ≤ n , m ≤ 5000 1\le n,m\le 5000 1n,m5000考虑 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示前 j j j 只老鼠进了前 i i i 个洞的最小距离, d p [ i ] [ j ] = min ⁡ ( d p [ i − 1 ] [ k ] + s u m [ i ] [ j ] − s u m [ i ] [ k ] ) dp[i][j]=\min(dp[i-1][k]+sum[i][j]-sum[i][k]) dp[i][j]=min(dp[i1][k]+sum[i][j]sum[i][k]),然后可以用单调队列优化成 O ( n m ) O(nm) O(nm)103

矩阵快速幂优化

题目题意思路代码
序列递推 f 1 = f 2 = 1 , f i = f i − 1 + f i − 2 + i 3 + 1 f_1=f_2=1,f_i=f_{i-1}+f_{i-2}+i^3+1 f1=f2=1,fi=fi1+fi2+i3+1,求 f n m o d    1 0 9 + 7 f_n\mod 10^9+7 fnmod109+7 [ 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 3 3 1 0 0 0 1 2 1 0 0 0 0 1 1 0 0 0 0 0 1 ] [ f i − 2 f i − 1 i 3 i 2 i 1 ] = [ f i − 1 f i ( i + 1 ) 3 ( i + 1 ) 2 i + 1 1 ] \begin{bmatrix}0&1&0&0&0&0\\1&1&1&0&0&1\\0&0&1&3&3&1\\0&0&0&1&2&1\\0&0&0&0&1&1\\0&0&0&0&0&1\end{bmatrix}\begin{bmatrix}f_{i-2}\\f_{i-1}\\i^3\\i^2\\i\\1\end{bmatrix}=\begin{bmatrix}f_i-1\\f_i\\(i+1)^3\\(i+1)^2\\i+1\\1\end{bmatrix} 010000110000011000003100003210011111 fi2fi1i3i2i1 = fi1fi(i+1)3(i+1)2i+11 -17
[NOI2012] 随机数生成器 X n + 1 = ( a X n + c )   m o d   m X_{n+1}=(aX_n +c)\bmod m Xn+1=(aXn+c)modm [ a c 0 1 ] [ x n 1 ] = [ x n + 1 1 ] \begin{bmatrix}a&c\\0&1\end{bmatrix}\begin{bmatrix}x_n\\1\end{bmatrix}=\begin{bmatrix}x_{n+1}\\1\end{bmatrix} [a0c1][xn1]=[xn+11],考虑 __int128 或龟速乘。-18
[SDOI2009] HH去散步给定一张无向图,求走 t t t 步能从 A A A B B B 的方案数 f [ i ] [ j ] f[i][j] f[i][j] 表示经过了 i i i 条边,最后经过第 j j j 条边的方案数,判掉反向边,用矩阵快速幂优化。-19
Magic Gems很多魔法宝石,每颗魔法宝石可以分解成 m m m 颗普通宝石,魔法宝石和普通宝石都占据 1 1 1 体积,普通宝石不能再分解。求有多少分解方案可占据 n n n 的空间。转移, f i = f i − 1 + f i − m f_i=f_{i-1}+f_{i-m} fi=fi1+fim,分别为普通和魔法宝石的转移。然后构造大小为 m m m 的矩阵即可。-20
Sonya and Informatics给一个长度为 n n n ( n ≤ 100 ) (n\leq 100) (n100) 0 / 1 0/1 0/1 串,进行 k k k ( k ≤ 1 0 9 ) (k \leq 10^9) (k109) 次操作,每次操作选择两个位置 i , j i,j i,j ( 1 ≤ i < j ≤ n ) (1 \leq i < j \leq n) (1i<jn),交换 i , j i,j i,j 上的数,求 k k k 次操作后,该 0 / 1 0/1 0/1 串变成非降序列的概率,答案对 1 0 9 + 7 10^9+7 109+7 取模。设共有 s s s 0 0 0,令 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示第 i i i 次交换 [ 1 , s ] [1,s] [1,s] j j j 0 0 0,然后是一通组合数,最后是矩阵快速幂优化即可。-21
Yet Another Number Sequence ∑ i = 1 n F i × i k m o d    1 0 9 + 7 \sum_{i=1}^n F_i\times i^k\mod 10^9+7 i=1nFi×ikmod109+7 F i F_i Fi 为斐波那契数列第 i i i 项。考虑用二项式定理展开,建立一个超大矩阵,外加一个前缀和。-23
Algebra Flash共有标号 1 ∼ n 1\sim n 1n 的格子,每个格子都有颜色 c i c_i ci。从 1 1 1号格子跳到 n n n 号格子,每次跳 1 1 1 2 2 2 格。初始时所有格子都未激活(包括 1 1 1 n n n),处于未激活的格子游戏会直接失败。花费 x k x_k xk 金币可以激活所有颜色为 k k k 的格子。求最少花多少钱可以完成。相邻两点必须选之一,可以将相邻的点连边,成为了一个最小点权覆盖问题,这是 N/P 难问题,考虑状压,但是 m m m 较大,所以可以用 meet in the middle,左边找到合法的状态,没有被选取的点互相之间是没有边的,是独立集,我们需要考虑两个集合 S , T S,T S,T 连在一起是否是合法的,反集 S ′ , T ′ S',T' S,T 两两之间应该没有边。我们考虑能否通过当前枚举的 S S S,找到合法的 T T T 呢?刚才我们已经找到了一个合法的约束,从此出发,可以直接得出,我们可通过 S ′ S' S 直接找到与它右边没有边 T ′ T' T 的集合, T ′ T' T 的任意子集跟 S ′ S' S 也一定没有边。-24

最长上升子序列

题目题意思路代码
护卫队 n n n 辆车想过一条长度为 s s s 的桥,每辆车有一个重量和速度,同一时间过桥的车的重量不能超过 W W W,求所有车过桥所需的最短时间。 n < 1000 n<1000 n<1000 g [ i ] g[i] g[i] 表示前 i i i 辆车过桥的最短时间,而能过桥的充要条件是过桥的车辆总和 ≤ W \le W W,而贡献则是一段的最慢车的过桥时间,即路程 ÷ \div ÷ 时间,注意这里的速度是 k m / h km/h km/h,而要求的时间是 m i n min min,需要单位换算和 long long16
膜拜 n n n 个人排成一排,每个人崇拜神犇甲或乙,分成若干个房间,要么这个房间内的所有人都崇拜一个人,要么两个神犇的膜拜者人数差不超过 m m m。求最少需要几个房间。 1 ≤ n , m ≤ 2500 1 \le n,m \le 2500 1n,m2500前缀和与差分, f [ i ] f[i] f[i] 表示前 i i i 个人最少需要的宿舍数。17
表达式的值现有一个长度为 L L L 的表达式,只有 and or ( ),求有多少种方式可以使表达式的值为 0 0 0,对 10007 10007 10007 取模。 0 ≤ L ≤ 1 0 5 0\le L\le 10^5 0L105类似表达式求值,可以用栈来模拟,优先级可以(<+<*<),然后模拟一下,最后求值, u u u 表示 0 0 0 v v v 表示 1 1 1,如果是 and u [ t ] = ( u [ t + 1 ] ∗ v [ t ] + u [ t ] ∗ v [ t + 1 ] + u [ t ] ∗ u [ t + 1 ] ) m o d    10007 , v [ t ] = v [ t ] ∗ v [ t + 1 ] m o d    10007 u[t]=(u[t+1]*v[t]+u[t]*v[t+1]+u[t]*u[t+1])\mod 10007,v[t]=v[t]*v[t+1]\mod 10007 u[t]=(u[t+1]v[t]+u[t]v[t+1]+u[t]u[t+1])mod10007,v[t]=v[t]v[t+1]mod10007;如果是 or v [ t ] = ( u [ t + 1 ] ∗ v [ t ] + u [ t ] ∗ v [ t + 1 ] + v [ t ] ∗ v [ t + 1 ] ) m o d    10007 , u [ t ] = u [ t ] ∗ u [ t + 1 ] v[t]=(u[t+1]*v[t]+u[t]*v[t+1]+v[t]*v[t+1])\mod 10007,u[t]=u[t]*u[t+1]%10007 v[t]=(u[t+1]v[t]+u[t]v[t+1]+v[t]v[t+1])mod10007,u[t]=u[t]u[t+1]18
CF467C George and Job给定一个长度为 n n n 的数组,从中选择 k k k 个长为 m m m 的子段(不重叠),使和最大。 k × m ≤ n ≤ 50000 k\times m\le n\le 50000 k×mn50000 [ i ] [ j ] [i][j] [i][j] 表示前 i i i 个数选 j j j 个序列得出的最大值。状态转移方程 f [ i ] [ j ] = max ⁡ ( f [ i − 1 ] [ j ] , f [ i − m ] [ j − 1 ] + s [ i ] − s [ i − m ] ) f[i][j]=\max(f[i−1][j],f[i−m][j−1]+s[i]−s[i−m]) f[i][j]=max(f[i1][j],f[im][j1]+s[i]s[im])。表示从上一层继承或者把这个区间使用掉, s [ i ] − s [ i − m ] s[i]−s[i−m] s[i]s[im] 即这一段的贡献。19
不等序列 n n n 的排列 a a a 中,有多少个排列恰好有 k k k a i < a i + 1 a_i<a_{i+1} ai<ai+1。答案对 2015 2015 2015 取模。 0 ≤ k < n ≤ 1000 0\leq k<n\leq 1000 0k<n1000 f ( i , j ) f(i,j) f(i,j) 表示前 i i i 个数的排列中 < < < 的个数为 j j j 的方案数。现在考虑前 i − 1 i-1 i1 个数都放好了,放第 i i i 个数。设数列为 { 4 , 3 , 2 , 1 , 5 , 6 } \{ 4,3,2,1,5,6\} {4,3,2,1,5,6},目前构成的符号序列为 { > , > , > , < , < } \{ >,>,>,<,<\} {>,>,>,<,<},放 7 7 7。如果把 7 7 7 放在 > > > 后,如放在 4 4 4 后,那么序列会变为 { < , > , > , > , < , < } \{<,>,>,>,<,<\} {<,>,>,>,<,<},把其前面的 > > > 变为 < < <,然后多了 1 1 1 > > >,所以总共增加了 1 1 1 < < <,而根据状态, j j j 用来表示 < < < 的个数,故 ( i − 1 ) − ( j − 1 ) = i − j (i-1)-(j-1)=i-j (i1)(j1)=ij 个都是 > > >。所以 f ( i , j ) = f ( i − 1 , j − 1 ) × ( i − j ) f(i,j)=f(i-1,j-1)\times(i-j) f(i,j)=f(i1,j1)×(ij)。而如果放在 < < < 后面,只会增加 > > >,还有 1 1 1 种情况是把 i i i 放在最前面,也会增加 1 1 1 > > >,所以 f ( i , j ) = f ( i − 1 , j ) × ( j + 1 ) f(i,j)=f(i-1,j)\times(j+1) f(i,j)=f(i1,j)×(j+1)。综上所述, f ( i , j ) = f ( i − 1 , j − 1 ) × ( i − j ) + f ( i − 1 , j ) × ( j + 1 ) f(i,j)=f(i-1,j-1)\times(i-j)+f(i-1,j)\times(j+1) f(i,j)=f(i1,j1)×(ij)+f(i1,j)×(j+1)20
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值