- 博客(24)
- 收藏
- 关注
原创 cf 218D
给出n-1条边,dp[i]为i为根需改变的边数使得i能到达任意一个点。 升序输出最小的dp(i)的下标。#include<stdio.h>#include<string.h>#include<iostream>#include<vector>#include<algorithm>using namespace std;const int maxn=2*100000+10,inf=1e9
2016-08-11 14:36:01
403
原创 树形DPpoj2152
题目描述:有n个城镇, 每个城镇在D(i)距离内需要至少有一个消防站,在每个城镇修建一个消防站需花费W(i),给出n个城市之间的网络图,问修建费用最少。主要还是看了陈启峰大牛的论文才能弄懂。 做法:设dp(i)(j)为 ①在以为根的子树里修建一些消防站; ②在结点必须修建一个消防站; ③以为根的子树内的每个结点在不超过距离的前提下,选择一个在子树内或结点上的消防站作为负责站; ④结点必须选
2016-08-08 17:40:15
423
原创 树形DPpoj3162
题意给出n-1条边,每个点有一个最远距离,为最长的一段区间,这个区间内的最远距离最大值和最小值的差不超过m。 这道题我最先跑最远距离用的是取子结点和父亲节点过来的最大值的方法,但是一直超时,我想应该是用的vector存边导致的吧(方便坑人。。)后来用另外一种方法求。求出最远距离后就是两个指针一起跑,然后要得到这两个指针区间的最大值和最小值,可以用线段树也可以用单调队列,我用的单调队列,代码如下#i
2016-08-08 15:29:42
610
原创 树形DP poj1741
题目描述:有n个点和n-1条边,dist(u,v)为u和v之间的最小距离,问两个点之间的dist(u,v)<=k的uv对数。 做法:假如枚举每一个点暴力跑肯定是超时的,那么这道题就需要lgn的级数来做,看了大牛们的做法是树上分治。大体思想为每回求出当前的树重心,以重心为根得到重心到子结点<=k的距离,大于k就没必要要了。对得到距离进行排序,然后可以两边从中间跑,当dis(l)+dis(r)<=k时
2016-08-07 15:52:00
368
原创 树形DPhdu2196
给你n个电脑,每两台电脑之间有权值,给出n-1条边,问每台电脑距离其它电脑最远的距离。 这道题最开始我是先随便选个点跑dfs,得到当前节点距离最远距离的点j,然后从j开始跑更新子节点从父亲节点来的最大值,然后再得到当前节点距离最远的点k,然后从k再开始跑更新子节点从父亲节点来的最大值。最后输出即可,可总感觉会有bug但太弱菜无法证明。之后发现菊苣们都是对当前节点考虑,只需要更新从子节点来的最大距离
2016-08-04 16:03:09
254
原创 树形DPhdu1502
题目描述:每个节点有权值,不能同时选择相邻的两个节点,问最后选的最大价值。 贪心的想法是要不选子节点,要不选父亲节点,可是有可能最优的是两个节点都不选。 那么就是类似01背包选择路线,来个dp[i][2],0表示不选,1表示选,那么从叶子节点往根节点不断更新就好了,状态转移方程 dp[i][1]=sum(dp[j][0]) dp[i][0]=sum(max(dp[j][1].dp[j][0]
2016-08-04 15:50:47
282
原创 数位DPhdu4507
题目如下 求[l , r] 中 如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关—— 1、整数中某一位是7; 2、整数的每一位加起来的和是7的整数倍; 3、这个整数是7的整数倍; 吉哥想知道在一定区间内和7无关的数字的平方和,区间范围在1-10^18. 根据题意我们的状态为dp[i][j][k],表示之前的整数和对7的余数为j,之前的整数对7的余数为k,在第
2016-08-02 13:50:46
320
原创 KMP
KMP算法是用来解决两个字符串匹配的十分神奇的O(n)算法。最主要的在于对于目标串的处理,有一个名为next的数组,得到的是字符当前点的后缀和字符的前缀能匹配相等的最大值。用O(n)求出。然后当对模式串进行匹配时用next数组进行转移,模式串遍历需要O(m)时间,对整体而言,个人觉得匹配串next跳的总次数会<2*O(n),即可看成O(n)时间,那么整体时间复杂度为O(m+n).这篇博客讲的很棒:h
2016-07-26 10:35:58
193
原创 manacher
最平常的算法是O(n^3)暴力枚举的。O(n^2)的是从中开始枚举,对奇数串和偶数串分别处理。而manacher采取了增加字符的方式避开了奇偶的讨论,而且达到了理论的下界O(n)的时间复杂度。设mx为字符串能往右延伸的最大点,id为最大点时的对称点。设p数组为当前点能延伸距离,j点为i关于id的对称点,则j=2*id-i,(0i时表明最大延伸距离大于当前点,即当前点能向右延伸。但是只能取p[j]和
2016-07-26 09:59:02
266
原创 ZOJ 3494 BCD Code
数位DP+自动机的结合,到现在发现对于题目的算法而言,我们都能学会,但是欠缺的是需要一点点细化而成的一步步想法与算法相结合。 以后一定要静下心来一点点细化的想。多的不说了,代码如下#include#include#include#include#includeusing namespace std;const int INF=1e9;const int MOD=20090
2016-05-20 00:17:49
276
原创 HDU 3247 Resource Archiver
给n个源串和m个病毒串,求包含所有源串但不包含任何病毒串的串的最短长度。利用源串和病毒串建立自动机,当为源串时end记录下标,病毒串时end标记为-1,然后在跑bfs时如果当前节点的fail指向节点的end为-1时,当前节点也需标记为-1,否则end[p]|=end[fail[p]].然后用dp[i][j]跑状压dp,i表示当前包含串的状态,j为当前节点状态,然后还需用一个二维数组表示mark[i
2016-05-19 23:43:13
316
原创 HDU 3341 Lost's revenge
给定n个模式串和一个目标串,求将目标串重排列后所能包含的最多的模式串个数。可以开个dp[s][a][c][g][t]来记录状态转移,s为结点状态,但是a,c,g,t的值范围为[0,40],很明显数组爆了,于是有个很神奇的方法,可以利用状态压缩把状态压成最多11*11*11*11的大小来标记a,c,g,t. num[4]来记录a,c,g,t出现的次数。bits[4]代表对应的权值,那么bits[0]
2016-05-19 21:32:09
271
原创 ZOJ 3228 Searching the String
给定一个模式串和n个目标串和对应的权值,当为0时求目标串在模式串里的出现次数(可重叠),当为1是可重叠。主要还是利用fail指针进行判断,当可重叠时直接累加end数组就可,不可重叠时需记录当前串的长度l和之前匹配到的最大下标p,如果l+p#include#include#include#include#includeusing namespace std;const int I
2016-05-19 21:23:41
419
原创 HDU 2457 DNA repair
给定n个模式串,一个目标串,求目标串修改最少多少次可以使其不包含任何模式串。用二维dp来求,主要是要构建出DFA,具体看之前的的poj2778里的链接。然后就是判断转移时是否需要+1,和利用end数组判断当前是否可以转移。代码如下#include#include#include#include#includeusing namespace std;const int INF=1
2016-05-19 21:17:37
322
原创 HDU 2296 Ring
给定m个模式串和对应的权值,求长度为n的包含总权值最大的目标串,如果有多个解输出最短的个,如果还有多个解输出字典序最小的个。end数组记录权值后用dp来跑,字符串处理会麻烦些,代码如下#include#include#include#include#includeusing namespace std;const int INF=1e9;const int MOD=20090
2016-05-19 21:14:00
202
原创 HDU 2825 Wireless Password
给定m个模式串,求至少包含k个模式串长度为n的目标串的种数MOD20090717。end数组记录为模式串下标的二进制数,然后利用状态压缩dp来求解,dp[i][j][k],i为当前串长度,j为当前结点状态,s为包含串状态。最后答案为dp[n][i][j],i为枚举的所有结点,j为包含串转态大于等于k时的值,代码如下#include#include#include#include#i
2016-05-19 21:00:44
243
原创 POJ 1625 Censored!
给定p个模式串,求长度为m,字符仅由给出的n个字符构成,用mp数组标记下。然后和之前的几道类似,利用end和next数组得到转态转移数组,然后由于题目数据不像之前的那么大,可以用dp[i][j]来进行状态转移,i代表当前串长度,j为当前状态。但是由于答案很大需要用到高精度。代码如下#include#include#include#include#includeusing name
2016-05-19 20:48:27
325
原创 HDU 2243 考研路茫茫――单词情结
这道题和poj2778类似都需要利用end数组和next数组的特性构建状态数组,不过这里是需要经过至少一个目标串,而且长度是不小于L的,即需要长度为1~L时的种数和。然后我们可以求出总数后减去不经过目标串的和,剩下的就是我们要的答案。设总数的数组为f[n],当n为1时答案为26,n为2时为26+26^2,即f[n]=(f[n-1]+1)*26;由于n等于L小于2^31,所以一样用矩阵快速幂求出再减
2016-05-19 20:37:27
752
原创 POJ 2778 DNA Sequence
给m个长度不超过10的模式串,求长度为n小于200000000的不包含任意一个模式串的种数。最开始最这道题的时候毫无头绪,最后看了这篇文章才理解了:(http://www.cnblogs.com/Booble/archive/2010/12/09/1901626.html),但是首先还要知道矩阵的一些应用:(http://www.matrix67.com/blog/archives/276)
2016-05-19 20:19:31
231
原创 HDU 3065 病毒侵袭持续中
和hdu2222类似,一样的开个数组标记下出现次数就好,代码如下#include#include#include#include#include#includeusing namespace std;char a[1010][55];struct Tree{ int next[500010][128],fail[500010],end[500010]; int ro
2016-05-19 20:15:58
224
原创 HDU 2896 病毒侵袭
end数组记录下模式串下标传参需大于0因为同时也需要记录是否为尾串。然后建好自动机。在query操作时,开个数组标记下经过了哪些目标串,即mark下end数组。代码如下#include#include#include#include#include#includeusing namespace std;struct Tree{ int next[500010][12
2016-05-19 20:09:41
223
原创 HDU2222Keywords Search
题意:给n1000000的模式串。用模式串建立好自动机然后在模式串上搜索就好了#include#include#include#include#include#includeusing namespace std;struct Tree{ int next[500010][26],fail[500010],end[500010]; int root,L; int
2016-05-19 20:00:29
298
原创 差和问题
差和问题刚刚把这道题A了,是之前比赛时没做的题。也正好是第一篇文章,本来很早便该写的,想来不知是太懒还是什么。 原题链接:http://www.51nod.com/contest/problem.html#!problemId=1394 是中文题,便不用再说题意了。 最开始很容易想到的便是更新总和和总个数,对于一个新插入的点而言,维护出比它小的个数和值总和。设sum,sumn,ans,
2015-12-02 22:03:26
329
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人