- 博客(14)
- 收藏
- 关注
原创 回文串算法Manacher
回文串算法Manacher首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号。比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#。 为了进一步减少编码的复杂度,可以在字符串的开始加入另一个特殊字符,这样就不用特殊处理越界问题,比如#a#b#a#。 下面以字符串12212321为例,经过上一步,变成了 S[] =
2017-12-26 20:31:46 456
原创 HDU 5371
HDU 5371题意: 长度为n 的数列,现在有一种对称形式为aba (其中b与a对称),输出满足题意的最长的数列长度。思路: 用Manacher求出辅助数组Mp,然后重点来了。 若想求出上面的形式,不妨枚举b的起点,那么直接判断第二个a是否满足即可,还是利用到Mp的性质。#include <iostream>#include <cstdio>#include <cstring
2017-12-26 20:31:00 420
原创 POJ1849
POJ1849题意: 有一颗n个结点的带权的无向树, 在s结点放两个机器人, 这两个机器人会把树的每条边都走一遍, 但是最后机器人不要求回到出发点. 问你两个机器人走的路总长之和的最小值是多少?思路:1. 假设只有1个机器人遍历树,且要求回到原点, 它最少需要走多少路? 答: 它需要走树总长sum的两倍, 即每条树边它都要走两次才行. 这个结论画个图就明白了, 对于每条边,
2017-12-24 21:08:57 382
原创 Gym - 101522B树的直径
Gym - 101522B题意: 给出一棵树,然后按照所给出的方式建立新的边,然后可以一层层的建边直到无边可建。问需要多少个小时,每一个小时可以建立一条边,可以多线程建立。思路: 画图可以找到规律,最坏的情况是n个点是一个线性的,那么时间将是最长,根据线性找规律发现其长度与时间是以2倍递增的,每一个新的小时便可以在原来的基础上画2倍的线,所以找出最长边然后判断2的ans次方即可。#inc
2017-12-23 17:04:47 407
原创 Hiho 1044 状态压缩dp
Hiho 1044题意: 有n个座位连续分布,现在给出限制条件m个连续座位上最多可以打扫q个位置,问最多能打扫多少垃圾。思路: 对于前面的状态枚举每一种可能,对于当前状态只有两种选择,分别计算即可。#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std
2017-12-17 18:30:09 324
原创 Gym 101617H dfs + 离散化 + 枚举
Gym 101617H题意: 有n个房间,m个门,k个桥,每一个门只允许特殊范围编号的人通过,问从出发点s到t可以有多少人通过。思路: 读完题发现k没有什么作用。。 对于这样的题在比赛的时候并没有读,太菜!从答案来看求的人数,通过题意可以发现这必然是一个连续的区间,左右端点不知道的情况下很难暴力,也无法枚举答案,因为很难验证。 正解很巧妙,对于答案所在的区间必然是存在于某几个
2017-12-17 16:38:59 348
原创 Gym 101617J dp
Gym 101617J题意: n个金矿,每一个金矿都有一个初始值代表第一天里面所含的金子数量,每天减少di,现在从金矿1出发,问最多能获得多少金子。思路: 时间是最难解决的问题,因为时刻在变化,但是如果能够对时间做处理,那么题目就很简单了。 不妨枚举时间和前一个所在位置的状态,当时间和状态都满足的时候才可以继续走。#include <iostream>#include <cstd
2017-12-16 20:46:54 294
原创 Gym 101617Jbfs+优先队列
Gym 101617J题意: n个金矿,每一个金矿都有一个初始值代表第一天里面所含的金子数量,每天减少di,现在从金矿1出发,问最多能获得多少金子。思路: 用bfs的方式思考,对于每一个状态就是沿着路径暴力搜索,利用bfs层的思想,对于采金矿的时间也是合理的,但是这样会超时,所以需要用到优化。1. 对于时间有一个最大的时间,可以通过输入算出2. 对于某一个金矿的到达存在不同的方式,记录
2017-12-15 17:49:28 416
原创 Gym 101617D dp
Gym 101617D题意: 有一个nXn的图,由.和#组成,现在从1,1出发,每次跳最多k个格子,落点不能是#,问到(n,n)最少需要几步,如果无法到达则输出-1.注意只能向右和下走。思路: 此题可以从dp方式来思考,当走到当前一步时,最重要的是判断从哪里开始,从上或者左,不妨开两个数组a和b分别记录行和列的信息:a[j]a[j] 保存当前j列中.所在的位置b[i]b[i] 表示能够到
2017-12-15 12:49:02 288
原创 Gym 101617D 线段树
Gym 101617D题意: 有一个nXn的图,由.和#组成,现在从1,1出发,每次跳最多k个格子,落点不能是#,问到(n,n)最少需要几步,如果无法到达则输出-1.注意只能向右和下走。思路: 直接bfs查询会超时,因为2000的数据会存很多点,但是如果对能到达的格子快速查找最小的步数可以用高级数据结构来完成,线段树。对于每一行和每一列用线段树维护#include <iostream
2017-12-15 12:48:33 260
原创 HDU 5459 根据题意找规律
HDU 5459 根据题意找规律题意: 求一个字符串所有c字符位置到其它位置所需的步数和。思路: 就根据题目的意思,如果要求出下一项则需要前两项的和加上前两项移动需要的步数,此时如果能从这里想的话就很简单了。#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef long lo
2017-12-08 19:52:59 364
原创 POJ 3167
POJ 3167题意: 原串长度为n,匹配串长度为m,输出匹配串在原串中出现几次,并且输出其出现的位置。思路: 利用kmp的思想,求出Next数组,求的方法是对于数字的排列存在规律,因为两个数列不同只能比较相对大小,其体现在当前数字之前的比其小的个数和与之相等的个数,预处理其存在的个数。 as[i][j]as[i][j] : 在a[i]a[i] 位置之前(包括本身)k数字存在的个数
2017-12-05 22:31:46 424
原创 HDU 3374
HDU 3374题意: 字符串长度为n(n<=1000000),问从哪个位置循环是最大字符串,从哪一个字符串循环时最小字符串,如果存在多个输出最大、最小的位置以及有多少个。思路: 利用kmp算出有多少个循环,便是多少个。 利用最大和最小表示法求出位置,注意输出最小的位置。#include <iostream>#include <cstring>#include <cstdio>
2017-12-03 20:29:27 500
原创 HDU5442 最小(大)表示法
最小(大)表示法 一个字符串扩增到两倍的时候,在0~n-1的范围中都可以通过循环找到与原字符串同构的字符串,但是其中有两个特殊的字符串,字典序最大和字典序最小(数字也可以当做字典序来处理),直接暴力找到最小或者最大的算法复杂度是O(n^2) ,有一种最小(大)表示法可以解决此问题。百度论文:https://wenku.baidu.com/view/c6c5e7335a8102d276a22fa
2017-12-02 10:12:43 356
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人