随笔分类 - 题解
摘要:传送门 解题思路 dp[i][j][k]表示从第i秒开始走走j秒从k工厂开始走的收益 maxx[i][j]表示从第i秒开始走j秒的最大收益。 则转移方程为: dp[i][j][k]=dp[i+1][j-1][(k+1)%n]+value[k][i]; maxx[i][j]=max(dp[i][j][
阅读全文
摘要:传送门 解题思路 很经典的区间dp问题。 我们可以发现删除和添加本质上是一样的。 所以可以直接对删除费用和添加费用取min。 跑一遍区间dp即可。 注意在读入string时,不能一位一位读,会RE。 正确的处理方法是直接cin>>S,或者用char数组代替string。 AC代码 #include<
阅读全文
摘要:传送门 解题思路 第一步,求出从每个墙壁开始刷是否合法。 第二步,合法的墙壁位置作为每个区间的左端点,变成区间覆盖问题。 第二步很显然是个贪心,重点是第一步如何解决。 我们设dp[i][j]表示从第i个墙壁第j个承包商开始刷能刷的墙壁的数量。 那么 当第j个承包商能刷第i个墙的时候,dp[i][j]
阅读全文
摘要:传送门 解题思路 重要思想:求 \(\sum{a_i^2}\) 相当于是取两遍球,取出来的序列相同的方案数。 于是设dp[i][j][l][r]表示第一次取上下分别取i/j个,第二次取上下分别取l/r个,两次取出相同序列的方案数。 转移就判断s1[i]/s2[j]和s1[l]/s2[r]之间的相等关
阅读全文
摘要:传送门 解题思路 设dp[i]表示在第i秒发车时前面的人一共等候了多少分钟。 朴素方程就是枚举 \(j=0\to (i-m)\) \(dp[i]=min(dp[i],dp[j]+i\times(cnt[i]-cnt[j])-(a[i]-a[j]))\) 其中 \(cnt[i]\) 为前 i 秒的人数
阅读全文
摘要:传送门 斜率优化 当求dp[i]最小值时,满足一次函数 \(y=kx+b\) 其中 y=dp[j] ,k 与 i 有关,x 与 j 有关,b中包含 dp[i]。 这时问题就可以转化为 在众多点(x,y)中找到一个点使得用斜率为k的直线切这个点时得到的截距b最小。很显然这时dp[i]从这个点转移过来最
阅读全文
摘要:传送门 解题思路 设dp[i][j]表示用前i个数,第一段山脉的高度为j,且j为山峰的方案数。 首先发现,dp[i][j]=dp[i][i-j+1],相当于把每个数取了个相反数,原来的山峰变山谷,山谷变山峰,方案数不变。 然后状态转移: j和j-1不相邻时:dp[i][j]=dp[i][j-1] 因
阅读全文
摘要:传送门 解题思路 设dp[i][j][k]为到前i行,有j列放了1个炮,k列放了两个炮的方案数。 显然讨论各种情况,从i-1进行转移即可。 可以滚动数组,但没必要。 一个不放:方案数等于dp[i-1][j][k]。 放一个,放在原来一个没有的列上:方案数等于dp[i-1][j-1][k]*(m-(j
阅读全文
摘要:传送门 解题思路 洛谷第一篇题解写的非常清楚 总结一下关键点,在图上求类似的期望步数,通常设计状态为dp[i]表示从i号点走到i+1号点的期望步数。 AC代码 #include<cstdio> #include<iostream> #include<cstring> #include<iomanip
阅读全文
摘要:传送门 解题思路 题意很简单,就是一个有特殊条件的01背包: 物品的体积很大,并且可以写成 \(a\times 2^b\) 的形式。 肯定是从这种特殊限制入手考虑,而且很容易想到按照二进制位分开做。 我们设 \(f[i][j]\) 表示对体积表示为 \(a\times 2^i\) 的物品进行01背包
阅读全文
摘要:传送门 多重背包 学了这么多年oi竟然只知道二进制拆分做法,白学了 多重背包就是每个物品有个数限制的01背包。 怎么做呢? 最暴力的是把每个物品拆成m[i]个物品,做01背包。 这样时间显然会爆炸。 二进制拆分优化 于是可以利用二进制性质,拆的时候打个包。 对于每种物品来说,每 \(1,2,4…2^
阅读全文
摘要:传送门 解题思路 对每一段时间进行操作,dp[i][j][k]表示在第k次操作结束时在位置(i,j)上的最大收益。 首先k这一维可以滚动数组优化掉。 然后对每个方向进行分类讨论,再对每一行/列加上一个单调队列优化即可。 注意碰到障碍就把队列清空,单调队列里的权值是dp值加(或者减)行数(或者列数)。
阅读全文
摘要:传送门 解题思路 很显然的一个线性dp,设dp[i][j]为到第i行第j列的最大power。 可以从前一行dp[i-1][j-t]~dp[i-1][j+t]转移过来。 用单调队列优化一下即可。 防止MLE可以用滚动数组优化,然后k个P点用二维map存一下。 注意: 不能直接 dp[j][now^1]
阅读全文
摘要:传送门 解题思路 设dp[i][j]为前i天第i天结束时有j张股票的最大收益, 首先令dp[i][j]=dp[i-1][j]。 买入转移方程: \(dp[i][j]=max(dp[i][j],dp[i-w-1][k]-(j-k)*ap)\quad\quad k=[j-as,j]\) 卖出转移方程:
阅读全文
摘要:传送门 第一年noip的考试题哇,满满的回忆 当年就因为这个题输出-1骗了5分拿了普及一等 解题思路 先二分答案,很显然答案满足单调性。 然后就是一个从限定范围转移过来的线性dp,用单调队列维护一下即可。 判断-1可以根据所有的正数加起来是否大于等于k。 细节还是很多的: dp数组初始化为一个很小的
阅读全文
摘要:传送门 解题思路 很巧妙的一个做法。 二分答案。 然后我们就可以通过把a[i]全部减去mid,把判断s~t个数的平均数是否大于mid,转化为是否存在一个区间,其平均数是否大于0。 乍一看仿佛没有什么优化,但是仔细想一想会发现,前者并不好实现,因为区间平均数与数字个数有关系,而后者只与和的正负有关系。
阅读全文
摘要:传送门 解题思路 很显然的一个单调队列优化dp。 但是有个细节也就是sub2的数据会卡掉,就是有的点可能根本到达不了。 例如: 输入: 5 3 4 0 1 2 3 4 5 输出: 4 而你不判断的话,会输出5。 怎么判断呢? 我们发现如果走不到某个点,则在求到这个点时,队列为空。 所以在队列是空的时
阅读全文
摘要:传送门 解题思路 \(n^2\) 遍历每个点,判断两个空洞之间是否能联通,若联通,则在两个点之间建一条边。 然后在能抵达上表面的点和能抵达下表面的点分别建边连向上表面/下表面,最后dfs判断上下表面是否联通即可。 总复杂度 \(O(n^2)\) AC代码 #include<iostream> #in
阅读全文
摘要:传送门 解题思路 用二维单调队列求出每个 \(n\times n\) 矩形的最大值和最小值。 其实就是先在每一行上做原数组单调队列,再维护每一个行上最大值/最小值所组成的数组的单调队列。 AC代码 (代码写复杂了) #include<iostream> #include<algorithm> #in
阅读全文
摘要:传送门 解题思路 单调栈的一道好题。 枚举矩阵右下角的端点。 首先可以发现,对于一个确定的右下角,对矩阵有限制的*的位置的行数是从左到右严格递增的。 也就是这个样子: 所有就可以用单调栈储存一下这个对答案有影响的1的位置。 于是我们就有了状态转移方程: \(dp[i][j]=dp[i][s.top(
阅读全文

浙公网安备 33010602011771号