随笔分类 - 题解
摘要:"题目" 易得该题目中的nn和kk具有单调性,满足二分的性质,因此该题目而已用二分来枚举nn,然后对于每个nn模拟出它所对应的kk,然后注意注意代码细节,并且当当前kk等于题目要求的kk时,要分别向左和右二分,才能找出所有情况。 c++ include define N 3000011
阅读全文
摘要:"题目" 贪心 贪心思路是先找到每个节点的到最深处的路径,并找到最大值。然后最后答案要加上该最大值和所有路径权值的差。 c++ include define N 600101 define int long long using namespace std; int n, root, cnt, an
阅读全文
摘要:"题目" DP, 用的dp[i][j]dp[i][j]表示ii之前的数选了jj个得到的最大结果,然后状态转移方程应该是 $$if (j \% t == 0)~~dp[i][j] = max(dp[i][j], max(dp[i 1][j] S[i], dp[i 1][j 1] + S[i] + B[i])
阅读全文
摘要:"题目" DP,需要注意边界上的问题。 状态定义dp[i]dp[i]为句子第i位去除字母的最小值,答案就是dp[len]dp[len]。 易得状态转移方程为: dp[i]=min(dp[i1]+1,dp[l]+(illen[j]))l是保留第j个字符串的右端点,len[j]是第j个字符串的长度。 c+
阅读全文
摘要:"题目" 一道非常好的树形DP。 状态:dp[u][n]为u的子树选n个黑点所能得到的收益最大值。 则最终的结果就是dp[root][k],root可以为任何值,为了方便,使root=1 然后考虑怎么状态转移,状态转移一般要从方程和边界入手,考虑用背包的思想,得到方程: $$ dp[
阅读全文
摘要:"题目" 图论综合题。 首先我们需要求出所有在公共最短路上的边,可以用预处理出最短路长度,然后枚举每一条边,依次判断即可。然后把这些边建到一个新图里,跑DP就好了。 此题的关键就是求出在公共最短路上的边。 c++ include define N 7001011 using namespace st
阅读全文
摘要:"题目" 区间DP,将maxn[i][j][k]表示为i到j区间内分为k个区间所得到的最大值,minn表示最小值。 然后可以得到状态转移方程: maxn[i][j][k]=max(maxn[i][j][k],maxn[i][l][k1](l到j的%10后的和))。 然后判断一
阅读全文
摘要:"题目" 搜索。并且通过题意所得到的信息先推出几个性质。 如果每个字母在开头的出现次数等于结尾的出现次数,则说明每个单词都有可能要成为起点。 而如果有字母在开头的出现次数比结尾的出现次数大,则只有以该字母为开头的单词才有机会成为起点,这样我们就可以只从他们开始dfs了。
阅读全文
摘要:"题目" dp状态定义的好题,初看这个题其实并不好想到他的状态,但是可以根据状态的定义,需要满足最优子结构。还有比较重要的一点就是方便转移方程。 首先我们定义dp[i]表示前i个数所能得到的最多个数,发现并不好转移,因此我们考虑多加一维状态j表示前i个数选j个的最多个数。这样就可以得出状态转移方程了
阅读全文
摘要:"题目" 一道入门的dp,首先要先看懂题目要求。 容易得出状态dp[i][j]定义为i时间疲劳度为j所得到的最大距离 有两个坑点,首先疲劳到0仍然可以继续疲劳。 有第一个方程: dp[i][0]=max(dp[i1][0],d[i][0]) 而如果要休息则一定要休息到疲劳值为0才可以停止。
阅读全文
摘要:每个海面要么放要么不放,因此可以用二分图匹配, 考虑把同一行内的能互相看到的点放到一个行块里,同一列内能看到的点放到一个列块里,然后每一个行块都可以和该行块里所有海面的列块连边,选了这个行块,就必须选且只选择一个该行块里的一个海面对应的列块。 c++ include include include
阅读全文
摘要:"题目" ) 二分好题 首先用二分找最小的绝对值差,对于每个a[i]都两个方向扫一遍,先都改成差满足的形式,然后再找a[k]等于0的情况,发现如果a[k]要变成0,则从他到左右两个方向上必会有两个连续的区间也随之变化, 然后我们有一点K, 使K点=0时,可以分别向左和右影响区间的值。并且影响之后的值
阅读全文
摘要:n SAT 是给定多个条件,问是否有一个赋值方式使所有条件得到满足。 每个条件都有n个变量, 而2 SAT 是存在时间复杂度为O(nm)或O(n+m)的做法(m是条件数)的算法的问题。 2 SAT往往是判断是否有方案使条件得到满足的一个算法。 建图: 求解2 SAT问题,需要转移到图上,对于
阅读全文
摘要:"题目" 首先分析数据范围发现m很大,所以线性做法肯定不行,因此考虑倍增,即预处理出每个点跳1次后的位置。然后只用两个数组类似于快速幂,推出每个点跳m次后的位置。 预处理离每个点第k小的点,可以用长度为k的尺子尺取。 c++ include include include include inclu
阅读全文
摘要:"题目" 该题目可以用辅助数组l[i], r[i]来指向以data[i]为最小值的左端点和右端点。然后最后枚举每个data[i]寻找每个data[i]的美丽值的最大值。 然后辅助数组可以用单调栈求出。 c++ include include include include include inclu
阅读全文
摘要:"题目" 先判断是否有解,然后开两个栈,分别存进入递归时间复杂度为O(1)的变量,和时间复杂度为O(n)的变量,最后取最大值。 include using namespace std; int T; int tong[1000100]; stack s, s2; int main() { // fr
阅读全文
摘要:"题目" DP,及DP的优化。 这个题显然是一个DP,状态也比较好定义, 定义dp[i]表示双方总共取i个数时,所得到的最大差值。 然后可以得出状态转移方程,即 $dp[i]=max(data[j] dp[j 1]);j define N 1010010 define int long long u
阅读全文
摘要:"题目" 字符串模拟+并查集 建立两个并查集分别存放每个变量的每一位数的祖先,一个是1一个是2 考虑每个字母的每一位的数都是唯一的,先模拟,记录每一个变量的每一位。 一一映射到方程中去,最后将两个方程进行一一比较,然后合并并查集。中间判断是否出现一位既是1又是2的情况 最后统计自由元的个数cnt,高
阅读全文
摘要:"题目" 单调队列+阅读理解 简化题意。 找到一个最长的区间使得区间每个点的r要大于该点之前的点的l。 然后可以用单调队列维护单调递减的l。最后尺取法O(n)枚举所有区间并取最大值。 单调队列可以快速找某个位置左右两侧比他大(或小)的数的位置
阅读全文