- 博客(182)
- 收藏
- 关注
原创 单源最短路的扩展应用
但是这里的DP关系不一定满足拓扑序,我们不妨把每一个DP抽象成空间的点,转移就是图上的走。首先按照题目把钥匙的门连起来,然后类似BFS的我们枚举每一个格子,循环4个方向,在不出界的条件下建边即可。主要结论:计数顺序可以顺着BFS,迪杰斯特拉,而贝尔曼之类的需要先建立好路径转移的拓扑序树,比较麻烦。类似的,无论是最短还是次短,优先队列弹出的一定是最终的答案,次数也不会在后面杯更新,正确性可知。证明就不详细展开了,最关键的就是确保第一次出了的点不会被后来的点更新。(01二进制)的最小步数。
2024-08-09 20:26:35 432
原创 单源最短路的综合应用
它的本质是动态规划,每一次在前一次的基础上松弛,保证了走到某一点在i步范围内是正确的,进而不断转移到n步,(这在没有负环的情况下显然是包含所有情况)而在本题中不断走一个环没有意义,也就是不存在负环。因此SPFA是适用的。现在我们主要求这个数组,假如图是严格的拓扑序,那么DP转移就十分明显,但是现在的图可能存在回路,直接DP会陷入死循环,于是我们考虑最短路的思想。注意虽然求单源最短路可以迪杰斯特拉,但是他的前提是每一次第一出队的一定是最短的,而显然这个条件在这里不成立(因为后面的可能比当前出对的更小)。
2024-08-07 20:22:45 684
原创 单源最短路的建图方式
我们考虑每一个物品当作点,用另一件替换它另需的花费作为有权边,再建立一个超级源点与每一个点相连表示直接购买的花费,于是我们从他跑到1即可。注意等级差距限制的调件,由于1一定满足,我们直接暴力枚举以他为右端点到以他为左端点的一系列区间即可。考虑对每一个线路内部互相连权值为1的边再跑个单源点最短路即可。这里权值都是1,跑个BFS即可。
2024-08-07 15:40:11 218
原创 DFS之迭代加深+双向DFS+IDA*
具体来说,我们人为的对这个“容器”的位置标号(从上到下,从左到右),同时我们把每一次操作对应的编号记下来,这样每次操作都可以快速找到进行操作位置的下标了。类似逆序对,我们考虑连接对(每一个后继点为前一个+1视为正确),每一次操作一共断开3个连接点,因此最多一次矫正3个。1.搜索时最坏情况可能搜到100层,比较深,但是答案应该比较浅,于是考虑迭代加深。搜索范围一层一层扩大,可以快速某些分支比较深,但是答案比较浅的问题。我们先想想直接DFS,那么差不多是1e12多的级别,于是我们对于。个,那么我们最少通过。
2024-08-04 13:56:17 433
原创 DFS之搜索顺序与剪枝
证明:假如3是某一个棒的第一个失败了,那么它一定存在在其他木棒中(假设4),那么木棒4中3的位置一定可以移到第一位,然后把棒4与3交换一下位置即可得出矛盾。证明:假如3是某一个棒的最后一个失败了,那么考虑把它放在其他木棒中(假设4),那么刚才那个木棒的填充最后一个的与放在4的那个交换一下一定也可,这也与前矛盾。具体的,我们先看看第一个桶里放什么,当然存在某个时刻,第一个桶再也放不下所有东西了,于是我们就再开一个桶。答案是否定的,因为假如再开一桶,把那个东西放到上一个桶中一定也是合法的,因此答案不会更优。
2024-08-03 23:17:53 935
原创 树形DP刷题
的度为1,那么它的流量就直接是流过他父亲的最大流量:即上述右部分。1.它自己子树的流量 2.流过它父亲的最大流量。度为1,那么它流向父亲的最大流量就是。为源点,从其流向子树的最大流量。首先,我们不妨以1为根节点,令。表示它流向整个水系的最大流量。事实上那个普通情况就是。
2024-08-03 16:42:32 358
原创 搜索之BFS刷题
假如一个点位于(1,1),那么它可以往左上脚走(-1,-1),而他经过的格子是(0,0)。这一题主要考的就是双端队列,但是我觉得这一题还考察了具体在点和块线上的位置移动实现过程。2.每一次BFS扩展的时候总是挑元素少的队列,这样效率更高。1.假如一个队列空了,那么从头到结尾与从结尾到头不连通。因此我们在写点走的方向时也应对应好走过的格子的方向。
2024-08-01 21:07:27 276
原创 区间DP---多边形 与金字塔
其实就是环形的石子合并,只不过由于乘法的存在还要记录一下最大值与最小值。)(非空)同时k属于偶数(由DFS序性质)。我们先固定最右一点,向左找与r相同的边界k(下面是状态的计算,我们以最右的子树为划分即可。区间的树的集合(由DFS知道连续的)
2024-08-01 20:24:28 623
原创 背包问题--陪审团
我们把每一个人看成一个物品,绝对值比较讨厌,我们先无视它,这样他的花费就是一个备选人员以及它的pd差值,他的贡献也就是p+d的值,想到了这一点,接下来的问题就是01背包了。最后我们从基准值开始同时往左右搜,这样也就符合了绝对值min为第一优先,max为第二优先的条件。
2024-07-31 15:41:07 259
原创 DP刷题(线性)
综上,满足这两个规则也就一定可以表示出来,因此我们可以忽略排的人的身高等细节问题,只需要知道每一行排了多少即可。的点多,那么就整体上移到A3一定更优,当A6到了A3,我们再类似的讨论A4,A5。我们考虑状态转移,发现直接求情况太多,于是我们考虑它可以转移到的状态即可。于是我们可以得出结论:存在一种构造B的方案,使B都在A中出现过。前排的人数:假如前排人多,那么后排的相对应的位置一定比前排低。首先,因为有一个人一定是在指定位置上,于是我们可以设状态为。2.我们对于每一行,排队的人都是从左到右连续的。
2024-07-31 13:16:45 543
原创 Codeforces Round #956 (Div. 2) and ByteRace 2024
联系到二进制异或的运算可以想到01Trie,对于每一个r,我们把它和mid放目前建立好的01Trie比较,假如在一个分支上mid是1,那么我们往异或r为0的路径走就一定可以,我们对pos进行更新。2.满足了条件1就一定可以转化过去,我们不妨从上到下,从左到右考虑每一个点,假如他和B一样就跳过,否则一定可以用2/1补上。3.反之奇偶相同一定可以,因为他们一定差2的倍数,而我们可以通过1与2交换,再2与1交换抵消若干个2.我们再开一个数组在add操作中把最新的值的走的路径上的最大下标进行更新维护即可。
2024-07-30 22:17:01 631
原创 DP的优化途径---单调队列
想到要维护出来每一个正方形的max与min,我们可以考虑先对行进行单调队列,求出行方向连续k个的最值,然后再对列进行一遍,这样就求出每一个正方行的最值了。)的min,考虑到j的范围是定值,用单调队列维护即可。于是我们把dp值放入单调队列即可。表示前i个的最大效率,答案就是。先维护出来前缀和,令。
2024-07-29 22:49:10 294
原创 Pinely Round 4 (Div. 1 + Div. 2)
2.假如为二分图,Bob的必胜策略就是在两个颜色中挑1/2放在他们各自染色的地方,当某个(1或者2,这里假设1)填满时,假如又是(1,3),那么就选3去填2剩下的部分。2,我们取D为最长边,我们假设A不属于D(其他同理),于是就是BCD,AEF,显然我们把BC优化成D的前面两个,AE优化成F前两个(前面有阻挡那就只可以保持现在了),因此他们二进制串的前两位表示的就是k,因此异或一定会变成0,也就是他们异或值是最小权值是4,因此一定是4的倍数,也就不是质数。,一定是需要4种的(因为1,3,4,6互连)
2024-07-29 21:34:59 1090
原创 牛客周赛 Round 53
单纯的只记录坐标与距离难以把所有状态维护清楚,于是我们再加一维:是否可以穿墙,同时为了代码方便,我们再开一维表示不能移动的某一方向。是否可以填满,先预处理所有a[i]可以通过除2得到的值,然后从大到小遍历,若为0直接不可能,否则再把它除2得到的数从原来存的地方减去即可。2.遇到墙,假如不可以穿忽略,否则穿,并把状态改为不可以串。先二分出一个mex的可能值,然后看看。1.枚举方向与当前禁的方向一致忽略。
2024-07-29 09:20:59 441
原创 Codeforces Round 957 (Div. 3)
这里有个细节:更新的时候要从大到小枚举,类似背包问题空间的优化,从小到大的化前面的会影响到后面的。由于x不是很大,开一个cun数组,对于刚枚举到的数。的遍历一遍,按照刚才的方法更新即可。也就是我们只要枚举x的因子即可,而一个数的因子一定。),这样b就可以直接得到,最后再检验一下即可。我们发现,这样其实有点多余,真正会产生影响的是。手搓样例,发现每次加1都是加当前最小的一个。最多不超过1e7的范围,我们不妨先从。显然:能放就放,不能放就再开一个。),这样我们就可以得到。然后就是更新,我们把从。
2024-07-28 17:38:27 619
原创 Codeforces Round 958 (Div. 2)
接着,后面一个一定是...1的形式,我们考虑这样的第3小101001,此时我们还是依据此时变0的位讨论,同样的可以推出101001相比于100101这种更优(我们把此时第二大的当成刚才最大的,也是同样的逻辑),依次类推即可。事实上,假如是一个....1的串那么由他得到答案,而我们一定可以在它与n之间插入101100,假如是...0的串,那101100显然更优,因为每一个位置上的1它存在101100也存在。我们倒着从大到小来:101101一定是第一个,第二个如果粗糙的想就是101100,因为他第二大。
2024-07-28 17:00:31 316
原创 Codeforces Round 960 (Div. 2)
于是我们可以记录a的平方次数,然后枚举k1-k(在5的时候b就以经比a的数据范围大了)即可。,如何凑出<=m的最大值。带来的影响:一方面假如。的存在,答案就显然是。
2024-07-28 16:13:34 405
原创 Codeforces Round 962 (Div. 3)
此时我们让k减掉x,可以发现此时的k一定小于等于n(假如大于n,我们对每一个a[i]再减去他们的b[i],这样就可以得到一个更小的x),于是我们就可以快乐地直接求了。我们提前一步维护mp,这样每次跟新mp只要+(j+2)即可,不然还要维护一个数组存j的位置。我们把0当成-1,1当成1,合法的区间也就是其值和为0,于是我们先处理出来前缀和sum。上的贡献,就和求j时的贡献一样(但是要*(j+2)),于是问题就是一个递推的过程。事实上,这个a数组的元素中的最大值一定是不严格递减的,最后一定会小于某一个值。
2024-07-28 14:20:29 414
原创 AtCoder Beginner Contest 364
对于A,B排个序,我们用最大的分别去与X,Y做差,最后取最小值即可。中a的个数,我们再二分一下,找出第一个不小于b-x的下标。表示到了第i个物品,甜度为j,咸度为k的选的最大数量。表示到了第i个物品,甜度为j,选了k个的最小咸度。下面问题就是给定一个x,如何求出。满足单调性,于是我们二分即可。,以及最后一个小于等于b+x的。最后对后两维扫一下即可。先给排个序,就是求在。
2024-07-28 13:11:05 432
原创 牛客周赛 Round 52VP(附D的详细证明)
假如afbc,afb1c(b<b1),若取afbc的a,我们不妨令它推出的最优解axyzb...b1,那么我们只要说明可以得到axyzb1....就可以得证。事实上我们不考虑b/b1后面的数,因为前面一定相同(axyz一定在b和b1的前面),因此我们不妨把b1按照b的流程对称走一遍就可以得到更优解。有两个一样的正数(包括0,0也只有用负数或者自己消去,与正数同一个性质)就直接消,剩下的我们看看正数与负数的数量分类讨论即可。我们令a为左括号数,b为右括号数,c为问号数(c1个变(,c2个变))。
2024-07-21 23:44:37 463
原创 数字转换(树形DP)
这样子,1--n的数就抽象成图中的点,我们进一步看看约数之和<自己的条件,这就避免了出现回路:假如有A,B,C构成一个回路,那么令A的约数之和为B,B的约数之和为C,那么A只能是C的约数之和,于是A>B>C>A,矛盾。考虑n<50000,直接暴力枚举肯定TLE,我们可以参考毕业季那题从因子出发枚举它倍数即可(nlogn)首先,对于一个数x,它对应一个其约数之和y,同时他们可以相互转换,于是我们可以给他们连一条边。于是整个图就可以抽象成森林。问题就是求每一个树的最大转换次数,也就是求最长链这一经典问题。
2024-07-21 22:31:45 261
原创 DP刷题(1500-1700)
首先,我们找到x的父亲k,up[x]=w[x][k]+maxx:这里w[x][k]表示x与k的边权,maxx就是父亲的up[k]和父亲的向下子链的max,这里注意,向下子链不可以穿过x,于是我们用d2[x]维护向下链的次大值,当我们发现最大值穿过时用次大值更新。所以我们需要知道最大子链是否穿过x,我们只要在第一遍dfs维护root选max时的儿子节点即可。我们发现这其实是用父节点更新儿子节点的过程,再来一遍DFS即可。比较容易想到区间DP,转换一下均方差定义用记忆化搜索就可以了。我们不妨以1为根建树。
2024-07-21 21:46:24 177
原创 Codeforces Round 960 (Div. 2)VP
00000222233344,我们可以看到就是左边多了个0,使整个序列向右平移一个,然后最边上的被挤了出去,因此我们可以从我们考虑倒数第i个数字a的贡献,它距尾还有n-i+1个距离:它还可以坚持n-i+1轮,也就是贡献a*(n-i+1),于是我们遍历一遍即可。对于连续的4,我们可以用两次操作2,也可以用1次操作1把它凸出来的消掉,然后剩下的22可以左右分或者直接删。很好证明:假如全是偶数,那么先手拿一个,后手一定可以拿相同的一个,于是先手必败。此时,从1--n,对于4直接用操作2,对于2直接操作1即可。
2024-07-21 14:22:58 776 2
原创 状压DP复盘
其次,一般的dp转移都是根据已有推出现在的状态,但是这题比较难实现,我们考虑另一种等价:根据现在去更新将来,具体的,f[0]=0的基线条件一定正确,对于从小到大枚举到的i,当我们取f[i]时,f[i]的值一定是正确的(具体的,假如i=10010,那么要可以转移到它的也只有10000,00010,00000,而他们是正确的,同时他们根据击落的所有情况对将来更新,因此f[i]一定是正确的)把这条件用到状态转移上:我们假设i的最低位0是第k个,我们只用枚举f[k][w](w从1--n)即可。
2024-07-20 21:14:12 323
原创 DP刷题(1500-1700)
我们令dfs(i,j,k)去找在i子树下最多可以分成>=k的连通块的个数,我们选1为根节点,对于它的子节点e,我们在去搜e子树的最好的划分,剩下的分给1,其他子节点同理,最后再看一看1连的连通块是否>=k即可。假如放在左上角,就贡献f[i-1],剩下的2n-2中划分两行也就是f[i-2],这样就得到递推公式了。综上,我们先根据落点的不同整理出一个干净的棋盘,我们令f[i]表示i*i规模的放法。我们考虑最终的情况一定是每一行只有一个,每一列也只有一个。首先不难想到二分一个x,那么我们如何check它呢?
2024-07-19 20:51:11 193
原创 Codeforces Round 959 sponsored by NEAR (Div. 1 + Div. 2) VP
首先我们枚举左端点为l的贡献,我们二分出来第一个从i---j的sum>x的j的位置,这样j不可以选,但是j前面到i的都是答案,而我们发现从j开始变成了0,我们再考虑j+1,j+2...n,因为在j的位置重置为0,因此其答案就是以j+1为左端点的答案,因此我们令dp[i]表示以i为左端点的贡献即可。首先由鸽巢原理:n个数,%(n-1)一定有两个一样,于是我们把那个联通,此时剩下n-1个连通块,对于%n-2,一定有两个连通块可以相连,依次类推,最终一定可以变成树。
2024-07-19 16:22:48 278
原创 动态规划的综合问题以及状态机模型
思路:考虑国王游戏的贪心思路,假设当i与i+1的能量都不会消耗到0,那么l/s小的放后面一定更优。这样我们就确定了选取顺序,下面就是选不选的问题。(本身背包问题不考虑选取的顺序,但是这里引入时间维度,对于选的物品需要安排顺序,也就是按照贪心的顺序取)我们把时间看成体积,当前的能量看成价值,同时为了方便转移让dp[i][j]中的j表示为正好为j。
2024-07-19 13:28:02 142
原创 DP问题之求具体方案+有依赖的背包问题+分组背包模型+方案数
注意到字典序min,我们可以反转顺序(按照原来顺序的话不知道1该不该选),也就是令f[i][j]定义为从第i个元素到最后一个元素总容量为j的最优解,答案就是f[1][m],我们再考虑具体方案,从1开始,能选就选。对于背包问题也就是看f[n][m]=f[n-1][m] or f[n-1][m-v]+w,相等时都可以选。核心思想:判断每一个物品是否被选,也就是根据一个结果推断前一个是否备选。核心思想:只要用f[i][j]表示dp[i][j]取max的方案数。
2024-07-19 10:31:08 443
原创 DP(1500-1700)(刷题)
我们先枚举第n+m+1走的答案,然后对于前面的一个人退出,看看有没有想选这个但是被迫走的,有的化取最近的更新,下面的一个空位由n+m+1填,反之若没有就只好让n+m+1来填,同时从后往前依次更新被迫的人的位置。
2024-07-18 20:56:22 501
原创 动态规划之数字三角形模型+最长上升子序列模型
就是取纸条的原题,我们令f[i1,j1,i2,j2]表示从(1,1),(1,1)分别走到(i1,j1),(i2,j2)的路径的max。i1+j1==i2+j2,于是我们可以把状态变为f[k,i1,i2]表示走到(i1,k-i1),(i2,k-i2)的最大值。表示max,然后考虑计算:先按是否包含a[i]分成两类:不包含:f[i-1][j],包含:a[i]==b[j]我们又可以把b分为以b[1]...b[j-1]以及空,对于b[k]就是f[i-1][k]+1。
2024-07-11 21:04:56 210
原创 数据结构模板2
具体就是先确定一个把字符串映射成一个数的函数,我们可以把它看出p进制再mod Q,A,B,等赋予不同的权值(最好不要0,否则AA,A就是同一个了),这里有个经验值,我们一般取p=131或者13331,Q=2^64,我们可以认为此时没有冲突值。这里有个技巧:我们开unsigned long long 这样modQ就可以用溢出直接代替了。这样+前缀哈希就可以计算出所有子串的哈希值:h[r]-h[l]*p^(r-l+1).哈希表:按照存储结构可以分为开放寻址法以及拉链法。
2024-07-10 13:35:07 886
原创 牛客周赛 Round 46VP
我们枚举的因子从2不断增大,一旦k*k>x,说明原来的数要么已经没有了质因子,要么还存在一个质因子(也就是x!首先我们先看看如何把一个数分解成质因数的乘积并计算出每一个质因数的次数,以前写过枚举2--n的试除法,这里TLE,其实只要枚举到i*i<=n即可。排个序,然后看看第一个>=k的位置,前面的维护好总的cnt*num,后面维护好每一个事物吃一次的前缀和*k即可。这样就是a1+y-1个空放y个板,方案就是Cy-1,a1+y-1=Ca1,a1+y-1。注意到这里的a1很小直接枚举即可。
2024-06-10 10:30:02 365
原创 牛客周赛 Round 45VP
我们记录每一个点的in的节点数,我们任意选2个一定是一个不规范的,而又因为每一个不规范的都一定有一点有两个in,因此我们只要减去in里选2个的情况即可。对于每一点,我们可以直接得到和它直接相邻的点,然后再把它们直接相连的点加起来看看有没有n即可。这场应该是十分仁慈的一场了。
2024-06-02 21:39:47 529
原创 牛客小白月赛95VP
于是dp[i]=mn[i]+1,现在我们考虑维护mn,假如一个值是第一次出现也就是mn[i]为无穷,那么此时i给mn带来的影响也就是当后面的出现i时,它可以作为一段被删的区间+1(但是前提是dp[i-1]要有解,否则也是白搭),而假如不是第一次出现,那么它的影响也就是优化当前的mn。但是复杂度还是超了,于是我们维护最小值,令mn[i]表示值为i时的位置的前一个的dp的最小值。1.转换后的图上有几个点是原图上没有的,我们需要去验证。早上蓝桥杯大寄,算是交了300元买了件T恤qaq。
2024-06-01 17:00:21 334
原创 蓝桥杯--杂题
ACWing里8/10,在洛谷竟AC了,不过正解应该是双向DFS+哈希(以后填)我们先枚举哪个国家赢了,然后再建一个数组排序即可。1.枚举的答案已经比当前的大了,return;3.如果当前的重量超过了答案,return;二分一下,然后把式子拆开用前缀和维护即可。2.后面的瓜加起来都不到要求的,4.将瓜从大到小排序。
2024-05-30 17:55:13 498
原创 蓝桥杯--LCA1
我们先把不删的sum维护出来,然后遍历跳过的点,假如a1,a2,a3,跳过2,那么答案就是sum-cost(a1,a2)-cost(a2,a3)+cost(a1,a3).
2024-05-30 13:45:58 516
原创 牛客周赛 Round 44VP
如何得到环的长度:DFS,遇到vis过的说明找到了环,return vis过的值,这样倒着把所有环的点记录了一遍,到vis那里时令flag=0,以免让前面的分支也被算进。于是我们只要维护环的长度,1--n的距离(不一定min),该距离走过的环的长度以及边的序号啊,环上的边。对于1-1e5的数据,我们先暴力枚举一下发现最多128个因子,于是我们就直接用前缀和维护即可。1.删的边在环上并且在得到1--n的路径上,那么就换成环的另一段即可。再遍历一遍1--n的距离,用DFS找到一条有解的路径即可。
2024-05-27 08:10:49 452
原创 牛客小白月赛94VP
这样我们就可以直接暴力了,考虑一下优化,当a与前面一个不相等时,答案就是a,因为a肯定比前面一个小,而已选的一定是前面的倍数,所以a自己满足,当相等是,我们从上次答案开始枚举即可。首先对于一个gcd a,答案肯定是它的倍数,我们取当前没有被去过的最小倍数即可(因为后面的gcd一定是前面的因子,因此只要是它的倍数,他们的地位就一样,为了方便选第一个。那么答案要符合,贪心一下就是把所有&ans==ans的全部&,根据&的单调递减,假如它<=k,符合,反之继续。
2024-05-25 09:23:55 325
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人