随笔分类 - Algorithm
摘要:题目:https://ac.nowcoder.com/acm/contest/11229/F 题解:https://www.bilibili.com/video/BV1Zv4y1u7hT?p=5&spm_id_from=pageDriver&vd_source=75ae018f8d1181302d7
阅读全文
摘要:整数部分,不断做除法,并取余数,最后倒置。 小数部分,不断做乘法,并取出整数部分。 例题 AcWing 4484. 有限小数 #include<bits/stdc++.h> using namespace std; typedef long long LL; LL GCD(LL a,LL b) {
阅读全文
摘要:AcWing 1073. 树的中心 #include<bits/stdc++.h> using namespace std; typedef long long LL; vector<int> adj[10010]; vector<int> w[10010]; int p[10010]; int w
阅读全文
摘要:有根树从根、无根树从任意一个节点开始处理即可 1、不考虑边权,考虑路径中点的个数,可以从任意一个节点开始进行DFS,DFS返回以当前节点为根的子树中,以当前节点为端点的最长路径。 经过当前节点的最长路径,即为以当前节点的子节点为端点的前2长的路径长度的和+1,并以此更新全局最长路径(直径)。 2、边
阅读全文
摘要:区间dp常用的实现方式有:迭代式和记忆化搜索式。 迭代式可以枚举左右端点,也可以考虑先枚举区间长度,这样小区间就会在大区间之前被计算。大区间通过分界点由小区间转移。 例题 AcWing 282. 石子合并 此题直接枚举区间长度和左端点,右端点不超过n。 AcWing 1068. 环形石子合并 此题可
阅读全文
摘要:前序遍历的第一个元素是根,设其为r,则可以在中序遍历中找到r,并分别确定左右子树的前序遍历和中序遍历。这样递归求解即可。 注意,在中序遍历中查找r时,可以不用遍历,而是预处理出每个r在中序遍历I中的位置invI,这样就可以在O(1)的时间查找到。 是否可以生成一棵二叉树的条件为,每一次递归,判断r在
阅读全文
摘要:当动态规划需要的数组范围太大,且当前状态只与前几维状态相关时,可以用滚动数组存储。 例如 二个滚动数组 dp[i&1]...=dp[i-1&1]... 三个滚动数组 dp[i%3]...=dp[(i-1)%3]....+dp[(i-2)%3].....;
阅读全文
摘要:对于一个首尾相接的数组,设其旋转k1、k2、k3...次后可以恢复原状。 且k1<k2<k3<...。 则可以肯定,k1为这个数组的循环节,且k2、k3...均为k1的倍数。 一种求循环节的方法为: 对长度为n的循环字符串,先从小到大遍历可能的循环节的长度i,判断是否n%i==0,然后对其中的除第一
阅读全文
摘要:291. 蒙德里安的梦想 此题使用状态压缩dp进行计算,状态表示使用一个数j,其中j的二进制位为1的位置表示1*2的第一个小方格并向后延伸。 由于1*2的第二个小方格和2*1的任意一个小方格与后面是没有联系的,对于后面的处理是等价的, 所以状态只用表示和后面产生联系的1*2的第一个小方格。 转移方法
阅读全文
摘要:根据三个等价条件,可以将n^2个数的GCD转化为n个数的GCD,且这n个数是连续的,可以通过线段树在log时间求解。 转化方式为 a与b的GCD=a与a-b的GCD,因为b=x*GCD。
阅读全文
摘要:设f(x)为x的最大平方除数(x的除数且为平方数),两数i与j相乘为平方数,等价于i/f(i)*j/f(j)为平方数且由于i / f(i)与j / f(j)不可能被任何质数整除两次以上则两数i与j相乘为平方数,等价于i / f(i)= j/ f(j)且f(i)可以在sqrt(i)的时间复杂度求出。
阅读全文
摘要:dp中的状态机模型会增加一维表示当前的状态。根据状态间的转移方式进行dp 1052. 设计密码 此题需要结合kmp和状态机模型 状态的定义是 dp[i][j]表示遍历到字母i,且匹配了长度为j的模板串,匹配模板串的长度即为状态。 状态的转移根据i-1位的匹配长度,以及i位的字母,计算i位的匹配长度。
阅读全文
摘要:对一个字符串的子字符串,判断回文一般需要O(n)的时间, 但是如果预先处理出子字符串的哈希值,则可以在O(1)的时间判断。 具体方法是,如果是小写字母,则可以用26进制数进行记录。 base=26; for(...) ha[i]=ha[i-1]*base+(str[i]-'a'); 再反着进行一次哈
阅读全文
摘要:背包问题可以用dp数组记录最大值。 可以新增另一个数组count,记录等于最大值的方案数, 这样,在算出最大值后,在求解一遍可以以最大值转移过来的方案数的和,即可得到最大值的方案数。 AcWing 11. 背包问题求方案数 代码如下: #include<bits/stdc++.h> using na
阅读全文
摘要:有依赖的背包问题,节点有树形结构的依赖。 可以递归计算。 递归的过程中,首先对节点的每个子树,计算在不同体积下的最大价值,即dp[u][i]。 dp[u][i]代表在节点u的子树中,选择不超过体积i的物品所得到的最大价值。 然后对当前节点,将每个子节点的每个体积看做分组背包问题中的物品求解。 在递归
阅读全文
摘要:二进制优化代码比单调队列优化代码更清晰好写。 可以将一维优化成log级别。 其思想是,将数量s,1+2+4+...+s0,对1、2、4、...、s0分别打包, 则小于s的任意一个数量均可由这些打包表示出来。 这样数量为s的多重背包,可分解为这些打包的01背包。 注意,由于此时物品数量增多,必须优化d
阅读全文
摘要:求 a/b(mod p) 其中,p是一个质数。 由费马小定理,有: b^(p-1)=1(mod p) 故 b^(p-2)=b^(-1)(mod p) 故 a/b(mod p) =a*b^(-1)(mod p)=a*b^(p-2)(mod p) 其中b^(p-2)可以用快速幂求解 注意:每一步都要取模
阅读全文
摘要:背包问题求方案时,可以进行dp过后,根据结果进行反推。 要求输出方案时,不能简化dp数组的维数。 当需要以字典序最小输出结果时,可以考虑从后向考虑物品,从后向前构建dp数组。 这样,反推的时候就可以从第一个物品开始考虑,就可以贪心的解决字典序问题。 (也可以使用标记数组解) 例题 AcWing12.
阅读全文
摘要:经典数学问题,在一根棍上多个蚂蚁,同时有不同的行走方向和相同的行走速度。如果蚂蚁碰撞则反向。 则整个过程可以等价为,蚂蚁之间不碰撞而穿过。 例题:Kick Start Round C 2022 https://codingcompetitions.withgoogle.com/kickstart/r
阅读全文
摘要:1、对于体积至多为V 初始化全为0,转移时要求j-v[i]>=0(否则,j<v[i],不可能选) 2、对于体积恰好为V 初始化dp[0]为0,其余为正无穷,转移时要求j-v[i]>=0 3、对于体积至少为0 初始化dp[0]为0,其余为正无穷,转移时不做要求。如果j-v[i]<0,则从0转移(因为如
阅读全文

浙公网安备 33010602011771号