01 2024 档案
摘要:题意:每个人有一个happ值,n个人,n - 1条有向边,u是v的上司,求happy值最大。 限制条件是u和v不能同时参加。 分析:没想到一个v居然有很多上司,更没想到n-1条边居然是个森林。 //没想到,一个员工居然可以有那么多上司。。 void solve(){ int n; cin >> n;
阅读全文
摘要:题意:一个有根树,树枝上有苹果,问保留m个树枝,最多能保留多少个苹果。 分析:树形dp,给定了m树枝数,显然可能的状态集合应该是节点保留的边数以及对应的最大保留苹果数。不难设计出转移方程: dp[u][i] = max(dp[u][i], dp[v][i - j - 1] + w); void so
阅读全文
摘要:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=447&page=show_problem&problem=4183 题意:给定两个字符串a,b,问最少多少次操作可以把a变成b。每次操作可以选择一段
阅读全文
摘要:https://www.luogu.com.cn/problem/P1775 题意:合并石子,每次合并的代价为相邻两堆的重量,求最小代价。 分析:区间dp,枚举所有的状态为下一次的区间长度计算需要的子集做准备,初始dp[i][i] = 0,前缀和计算合成代价。 void solve(){ int n
阅读全文
摘要:题意:二维平面内n个糖果,问吃完所有糖果走的最小距离。 初始时坐标为0,0。 n <= 15 分析:经典状压模板题。 void solve(){ int n; cin >> n; vector<pair<double, double>> a(n); for (auto& x : a){ cin >>
阅读全文
摘要:https://www.acwing.com/problem/content/description/294/ 题意:n,m平面内,有些格子可以放士兵,士兵的攻击范围是一个十字形,在士兵不攻击其他士兵的前提下,求方格内最多放置的士兵数。 n <= 100, m <= 10 分析:状压dp,状态是三维
阅读全文
摘要:题意:n*m的平面,问有多少种方式能被1 * 2的小条子放满。n, m <= 11。 分析:状压DP。由上一行转到当前行。 定义状态竖着放的上半部分为1,可知上一行&当前行为0,并且上一行|当前行不含奇数长度0。剪枝 + 交换n,m降复杂度。 没想到如何表示状态跟转移 定义竖着木头的上半部分为1,其
阅读全文
摘要:题意:n个点,求从0~n-1的最短路径(经过每个点一次) n <= 20 分析:用二进制位表示经过了点的状态,枚举所有的状态 constexpr int inf = 0x3f3f3f3f; void solve(){ int n; cin >> n; vector<vector<int>> dist
阅读全文
摘要:https://www.luogu.com.cn/problem/P4124 题意:给区间[l, r], 求满足条件的手机号。条件:4,8不同时出现,有AAA数字出现,没有前导0。 分析:没有前导0,如果[1,x],x < 1e11, 直接return 0。 前缀差分,高位到低位,状态是前两位数字跟
阅读全文
摘要:https://www.luogu.com.cn/problem/P2657 题意:给定范围,求windy数个数。windy数是相邻数字差值至少为2的数。 分析:前缀和差分,数位dp,从高到低判。 这里记录前导0的意义在于,如果前面都是0,那么前面的这一位可以看做是-2,在当前的pos位可以选任何数
阅读全文
摘要:题意:统计区间内每个数字出现的次数 分析:前缀和差分,数位dp,从高到低考虑,有一种特殊情况是统计0出现的次数时,要考虑前导0 void solve(){ long long l, r; cin >> l >> r; vector<int> num; int digit; vector<vector
阅读全文
摘要:https://www.luogu.com.cn/problem/P4999 题意:给定区间[l, r],求[l,r]内所有数字的每位dight相加的总和。 分析:数位dp,前缀和差分,从最高位往最低位考虑。 //更好的理解dp[pos][sum], 当考虑pos位的时候,pos位肯定有一个sum值
阅读全文
摘要:题目链接:https://www.luogu.com.cn/problem/P1967 题意:n个点,m条边的图。q个询问,问u->v之间权值最小的边权值是多少(不要求走最短路径,只要经过路径上经过的最小的边的权值最大)。 分析:如果两点间有路径,那么优先走边权更大的边,所以先利用最大生成树算法构建
阅读全文
摘要:题意:n个节点m个询问,每次询问2个输入,u和v两个节点,代表u,v之间的路径权值+1。求m次询问后权值最大的节点。 分析:明显树上差分,将u,v作为区间起点,祖先作为和祖先的父亲作为差分区间结尾。 思考:为什么要从下往上差分,从上往下差分为什么不行呢 求LCA的时候算法写错了,往上跳的时候没跳u,
阅读全文
摘要:关于LCA的倍增跟ST的倍增:一个是树上从当前深度往上倍增,倍增上限不超过当前深度,一个是数组中从左往右倍增,倍增上限不超过右边界。 不过在树中倍增要先处理出当前点的深度才能进行倍增,而数组中可以直接根据下标跟有边界的距离计算。 void solve(){ int n, m, root; cin >
阅读全文
摘要:题意: 一颗树,从点1出发,初始代价是访问每个点1次回到点1。现在要加k <= 2条边,求加了边后的最小代价。 分析: 当k = 1时,代价就是初始代价-直径 + 1 当k = 2时,目前还不能理解 void solve(){ int n, k; cin >> n >> k; vector<vect
阅读全文
摘要:2次dfs solutions, 仅限边权为非负,或者没有边权(边权为1): void solve(){ int n; cin >> n; vector<vector<pair<int, int>>> al(n + 1); for (int i = 0; i < n - 1; ++i){ int u
阅读全文
摘要:没有题目链接,上个代码,是为了求解树的重心数量以及节点编号 void solve(){ int n; cin >> n; vector<vector<int>> al(n + 1); for (int i = 1; i < n; ++i){ int u, v; cin >> u >> v; al[u
阅读全文
摘要:题意:n个数m个查询,三种操作。 1:区间的数都+k。2:区间的数都*k。3:求区间和 分析:考虑如何设计区间更新规则。 对于lazy的更新:如果乘进来,那么和跟乘积都乘,然后和加上和。如果和进来直接加。如果同时进来,也是先乘再加。 对于区间sum的更新,按照先乘再加即可。 (突然发现lazy标记的
阅读全文
摘要:题意:给n个数,m个查询。查询有两种,第一种将[l,r]的数都开方。第二种对[l, r]求和。 分析:不用segmenttree,对于一个数开放次数不会超过10次。所以直接暴力开方,用dsu降时间复杂度,fenwicktree负责求区间和。 但是WA了3个点,不知道为什么,现在唯一能想到的原因就是输
阅读全文
摘要:题意:n<=40, m <= 1e18,n个数中,组合的和<=m的组合有多少种。 分析:n是40,双向广搜的思路,压缩搜索范围,分成2个 2^20进行搜索。 再二分查找合法的另一半中的元素数量 void solve(){ long long n, m; cin >> n >> m; vector<l
阅读全文
摘要:题意:给一个n个数字的集合,问集合中有多少个子集满足后面的条件。 其中条件是该集合可以分为两个独立子集,这两个子集的和相等。 分析:第一种思路是枚举所有的集合,然后对每个集合进行暴力枚举,时间复杂度O(1 << 40)得分45。 第二种思路是枚举所有的集合,然后对集合元素求和,转01背包问题,时间复
阅读全文
摘要:题意:给起始和终止串A和B,以及不超过6个字符串变换规则,求A->B能否在10步以内变换完成。 分析:暴力bfs每次有6条路可以走,时间复杂度是6^10 大概6e8的时间复杂度,会TLE。于是这题是一道经典的双向bfs。 直接开两个队列,两个map,暴力搜1~5步即可。 双向bfs的时间复杂度是2
阅读全文
摘要:问题描述:密码锁有起始和目标两个状态,状态有4个连续数字,数字范围是1~9。其中特殊情况9 + 1 = 0, 1 - 1 = 9。 每次操作可以交换相邻的两个锁上的数字,或者将该位上数字±1。求最小操作次数 分析:是一道双向广搜的题,但是这个题目的第一个思路就是枚举所有的排列组合状态,然后对每个状态
阅读全文