ACM算法问题
HZ-VUW
这个作者很懒,什么都没留下…
展开
-
HDU 3681 二分+状压+BFS
题意一个人要出逃,需要从F点出发,访问所有的Y点才可以成功出逃,这个人可以拥有一个能量为V的背包,每移动一格消耗1点能量,到达G点的时候可以补充满能量。问最少需要携带一个多小的背包,才能成功出逃。题解第一眼看见这道题的时候,想的只是一个普通的BFS。但是在用优先队列实现的时候出现了一些问题,不太好判断优先访问哪个点。倘若不进行优先访问的选择,允许重复访问同一个点,那么无论是时间上还是空间上都是不可承原创 2017-07-30 16:20:16 · 253 阅读 · 0 评论 -
HDU 3709 数位DP
题意如果把一个数拆分为,左半部分,右边部分和平衡点,左半部分力矩=右半部分力矩。则称这个数为平衡数。问某个区间内有多少个平衡数。题解数位DP的经典套路。首先拆分数位,然后根据记忆化搜索。这道题由于数最多只有19位,所以可以暴力枚举平衡点,于是DP数组涉及到三个状态,当前长度,平衡点位置,总力矩。总力矩<0的时候就再也无法达到力矩平衡,可以直接return 0。代码#include <iostream原创 2017-08-03 13:29:06 · 181 阅读 · 0 评论 -
HDU 4507 数位DP
题意问某个区间内与7无关的数的平方和%1e9+7的结果是多少。 与7无关即:不含7,可以被7整除,所有位加起来可以被7整除题解这道题不是一般的数位DP题,一般的数位DP题都是统计某个区间内有多少个这样的数。这种数位DP就很简单了,直接DFS记忆话搜索,过滤一些情况,就可以了。 这道题过滤情况没有什么难度,难点在于要求的是平方和,以及最后极其变态的MOD要求。 因为要求平方和,所以就必须要想办法原创 2017-08-03 19:55:08 · 221 阅读 · 0 评论 -
POJ 1160 普通区间DP||四边形优化DP
题意N个点修M个邮局,要求修建邮局最优,使得其他点到最近邮局的距离之和最小,问这个最小值是多少。题解这道题由于数据范围比较水,所以普通区间DP也可以70MS轻松过。不过这道题使用四边形优化的话会有更优秀的性能,可以使时间降到40MS。 首先的话,需要求出任意两点之间修一个邮局,其他点到这个邮局的距离之和。这里面涉及到一个式子,dis[i][j]=dis[i][j-1]+x[j]-x[(i+j)/2原创 2017-08-18 22:12:02 · 305 阅读 · 0 评论 -
ZOJ 3949 树形DP
题意给一棵树加一条边,使得根到所有点的距离之和最小,问最小的距离之和是多少。题解一道很考思维的树形DP。首先的话,先用简单DFS求出每个点的子节点数量和以及总路径长度。然后再尝试加边,计算加边以后能减少的距离。最后总路径长度-减少最大的距离=所求长度。 计算减少距离利用的是DFS的思想,对于细节的考量还是比较详细的。首先的话就是对于中点的划分。中点选取dep/2+1作为中点,可以证明dep-(de原创 2017-08-12 08:38:24 · 392 阅读 · 0 评论 -
HDU 3341 AC自动机+DP
题意给一堆模板串,以及一个文本串。文本串可以调换顺序,问经过一些调换后,最大能匹配的模板串数量是多少?题解状态转移方程还是很容易想出来的,毕竟AC自动机的状态转移很明显。基于last数组进行DP就行了。 这道题的难点在于文本串的状态表示。文本串长度为40,如果开一个40*40*40*40的数组表示状态,那么肯定会MLE。所以需要把文本串进行变进制压缩。变进制压缩的过程就是将ACGT根据相应的个数进原创 2017-08-12 12:35:51 · 247 阅读 · 0 评论 -
POJ 1180 斜率DP
题意要求将一组任务分成多个区块,每个任务都有相应的执行时间。执行每个区块的每个任务的代价为(区块执行完成的最后时间*每个任务的花费)。区块执行完成的最后时间为所有任务执行完成的最后时间+固定值M。问最小花费。题解状态转移方程是难点,其他的就是模板了。关于状态转移方程,需要逆序进行推倒。状态转移方程dp[i]=dp[j]+(m+t[i]-t[j])*c[i]。其中t代表逆推的时间和,也就是从N向前累加原创 2017-08-19 23:39:10 · 230 阅读 · 0 评论 -
HDU 6156 数位DP
题意给一个区间,求这个区间内的所有数在A进制到B进制下(回文数的个数*进制)+非回文数的个数。题解其实就是很普通的数位DP,只不过在状态记录上比较新颖。状态记录不再使用函数参数记录状态,而是使用一个数组来记录每一位的状态,因为DP是递归调用的,所以可以在对后面需要和前面相同的位进行判断,只有相同的情况才能进行下一步DFS。代码#include <iostream>#include<cstdio>原创 2017-08-20 10:35:43 · 266 阅读 · 0 评论 -
POJ 2018 斜率优化DP
题意给一堆数,选不少于F个数的子序列,求均值最大的子序列。题解最原始的斜率DP优化题目,最初出现在周源的国家队论文中。尽管这个题是最原始的题,但是这个题并不能用常用的套路。这个题的状态转移方程很明显,但是却不是标准的斜率优化方程(当然也差不多)。优化的话,基本上还是老套路,用一个单调队列进行优化。在选择最优元素的时候,对斜率进行判断,如果下一个点组成的斜率更大,那么将选择下一个元素。在插入元素的时候原创 2017-08-20 15:20:39 · 492 阅读 · 0 评论 -
UVALive 5097 斜率DP
题意有 N个人,挖K个洞,使得每个人能穿过去。每个人的面积为w*h。挖洞的花费为w*h。问最少花费题解首先需要对人进行排序,W从大到小进行排序。排序完成以后,从1到N进行扫描,移除无用元素(即H小于前面所有元素最大H的元素)。这样处理完成以后,整个序列W是单调递减的,H是单调递增的。于是列出状态转移方程,dp[i][j]=dp[i-1][a]+w[a+1]*h[j]。(其中A代表挖洞最后一个)原创 2017-08-17 15:05:32 · 255 阅读 · 0 评论 -
POJ 2778 AC自动机+矩阵快速幂
题意有M个字符串,这M个字符串不能出现在字符串中。要求字符串长度为N,问有多少种方案。题解首先,对于这道题,需要知道一个数学定理。对于一张图的邻接矩阵,邻接矩阵的N次幂就是两点距离为N的路径条数。 知道了上述定理以后,这道题就可以看作,字典树从0开始,到某个节点,路径长度为N的方案个数。因为存在不能出现的字符串,结合AC自动机便可解决该题。利用AC自动机对不能出现的字符串,以及后缀子串是不能出现的原创 2017-08-09 21:02:06 · 309 阅读 · 0 评论 -
HDU 1560 IDA*(迭代加深搜索)
题意:N个序列,只可能由ACGT组成。求最短公共序列。题解:暴力打表肯定超时。采用迭代加深搜索可以解决问题。迭代加深搜索其实就是有界的深度优先搜索。可以设置上界从1开始进行搜索(也就是假设最短公共序列的长度为1)。如果当前公共序列长度+某一序列未访问点的长度>上界,则返回Flase,并增加上界。直到所有序列的所有字符都已经被访问为止。代码:#include <iostream>#include<c原创 2017-07-18 11:22:29 · 485 阅读 · 0 评论 -
HDU 5336 暴力BFS
题意:初始有N个水滴群,有一个爆炸点,爆炸点会爆炸成四个小水滴,分别向四个方向流动。当流动到水滴群的时候,水滴群体积+1,如果组成的新水滴群体积>4,则新水滴群爆炸,水滴群消失,形成四个小水滴,分别流向四个方向。问第T秒,各水滴群的情况。题解:暴力BFS,模拟水滴的运动即可注意事项:要注意两个点,一个点是题目中提到如果小水滴同时到达一个水滴群,而这个水滴群恰好爆炸,则这些小水滴一起参与爆炸。 第二原创 2017-07-22 09:46:14 · 233 阅读 · 0 评论 -
POJ 2411 状压DP||组合数学
题意1*2的牌放入N*M的网格中,问有多少种摆放方案。题解两种解决方案。 第一种,组合数学有一个专门的公式解决这个问题。 感谢周伟大佬提供的公式,ORZ。。(同时强烈推荐读者阅读周伟的状压DP论文)第二种,状态压缩 相比于组合数学公式,状态压缩的效率就低很多,但是由于公式不太可能短时间内推导出来,所以在比赛和做题的时候,还是状态压缩方法比较通用和便捷一些。 关于这种放牌的问题,周伟大佬称原创 2017-07-31 15:40:42 · 380 阅读 · 0 评论 -
POJ 3001 暴力
题意某次调查有N个调查选项,已知每个调查选项的得票率(经过了四舍五入),问最少多少人参与了调查。题解这大概是这道题第一篇中文题解吧。。 暴力出奇迹,因为最多只有10000人参与投票,因此暴力尝试1至10000人即可。由于概率经过了四舍五入,因此还原的时候只能还原成一个区间,这个区间就是x-0.499到x+0.500(一定要注意精度问题,-0.49的精度不足以AC)。这样就可以计算出来是否可能有i个原创 2017-07-24 15:25:24 · 331 阅读 · 0 评论 -
ZOJ 3469 区间DP
题意一个人从X点出发给N个点送食物,速度为1/v,如果第xi个点的客人没有收到食物,那么他的不满意度将会增加bi每分钟。问不满意度最少为多少?题解很有趣的一道区间DP题,将出发点也放入点集中,排序,进行区间DP。 dp[i][j][0]代表该人在I处,I到J的所有客人都已配送完成时最少的不满意度。 dp[i][j][1]代表该人在J处,I到J的所有客人都已配送完成时最少的不满意度。 由此可以得原创 2017-08-01 21:07:33 · 186 阅读 · 0 评论 -
POJ 3737 三分
题意给一个圆锥的表面积,问体积最大是多少题解s=pi*r*l+pi*r*r v=pi*r*r*h/3 三分搜索r,下界设为0,上界设为sqrt(s/2/pi)(这么设置上界的原因是假设r=l,则r=sqrt(s/2/pi),但实际上由于r=sqrt(l*l-h*h),因此完全可以作为上界)。此外,在计算的时候,还用到了一个小技巧,PI可以用acos((double)(-1))来表示,如果用3.1原创 2017-07-24 17:33:50 · 305 阅读 · 0 评论 -
HDU 2196 树形DP
题意N台计算机,N-1条线相连,问这N台计算机每一台计算机到另一台计算机的最长距离是多少。题解一道很好的树形DP题目。首先的话,对于一个点要搞清楚寻找最长距离所能转移的三个状态。一种状态是沿着子节点DFS,寻找最长距离。第二种状态是,先向父节点走一步,然后沿着另一条线路DFS。第三种状态是,向父节点走多步。 针对这三种状态,可以使用一个二维DP数组对状态进行记录。注意事项这道题最重要的是想法,没有原创 2017-08-09 09:47:03 · 181 阅读 · 0 评论 -
POJ 3252 数位DP
题意如果一个数二进制表示0的数量大于等于1的数量,则称这个数为Round数。问某个区间内Round数的数量。题解数位DP,状态迁移还是比较难想的。我选择了网上大多数人的解决思路,记忆化搜索解决。 dp[len][num1][num0] len代表当前位置,num1代表1的个数,num0代表0的个数。 至于DFS函数,dfs(int len,int num1,int num0,bool first原创 2017-08-02 21:46:05 · 205 阅读 · 0 评论 -
HDU 3652 数位DP
题意问1到N,数字包含“13”且能被13整除的数字有多少个题解这道题和POJ 3252差不多,都是一个套路。首先把整数分位,然后按位进行DFS状态转移。这道题唯一比较重要的地方就是有个数学公式一定要想到,a%mod可以拆分为(如果a由bc组成)((b%mod)*c+d)%mod。有了这个公式,MOD的结果状态就可以带到下一位进行处理。代码#include <iostream>#include<cs原创 2017-08-02 22:16:43 · 183 阅读 · 0 评论 -
HDU 4003 树形DP+背包
题意给一棵树,一堆机器人从根节点向下进行搜索。要求搜索到每个叶子节点,机器人可以向回走。问机器人行走最短总路径和是多少。题解树形DP+背包,不过不能算是严谨的背包。DP方程不太好想,dp[i][j]代表i点有j个机器人走了便不再回来。DP分两步,第一步是假设所有的机器人走了以后都会回来,dp[s][j]+=dp[nd.to][0]+2*nd.val。第二步是派一部分机器人走下去便不用回来,dp[s]原创 2017-08-21 16:58:41 · 237 阅读 · 0 评论 -
UVA11270 轮廓线DP
题意有很多个2*1的骨牌,放到N*M的棋盘中,问有多少种铺满棋盘的方法。题解对于这道题,由于骨牌涉及了多行,所以利用传统的状压DP是无法解决的。在这里需要运用一种叫轮廓线DP的技巧。轮廓线DP不再是针对某一行或者某一列进行状态转移,而是以每一个元素为中心,进行状态转移。 很明显,对于一个位置有三种选择,不放,横放,竖放。对于不放这种选择来说,只需要保证上一列这个位置的元素不为空就可以进行状态转移。原创 2017-09-03 21:44:14 · 252 阅读 · 0 评论 -
HDU 4455 DP+树状数组
题意给一串数字,里面有N个数字。有Q次查询,每次查询长度为X的串,不相同的数字个数之和。题解很难看出来是DP,不过考虑到查询问题,并且无法用普通的数据结构进行解决,同时长度之间存在利用关系,因此可以用DP解决。 首先对于长度为1的串,很明显可以得到dp[1]=n。对于长度为2的串,我们首先要删除末尾的一个长度为1的串,然后对于每个串再加上一个值,如果新增了一个数字,那么这个值就是1,否则就是0。然原创 2017-10-08 00:34:53 · 592 阅读 · 0 评论 -
HDU 6002 贪心
题意每个人有一个排行榜,目前已知tom的排行榜,以及一部分的朋友关系,以及每个人在排行榜中排第一的次数。问tom的朋友最少在多少个陌生人的榜单中排第一。题解首先的话,很容易分析出,两个人组成一个榜单,这样的话会是结果最优。我们首先可以求出来符合所有条件的情况下,一个人榜单中排第一的最大排名位置(假设排名第一是最小排名位置)。 需要注意是的,除了给出的朋友关系条件,由于有一部分人在榜单中的排名大于t原创 2017-09-21 21:01:53 · 531 阅读 · 0 评论 -
HihoCoder 1251 BFS预处理
题意给一堆字符串,问转换成另一种字符串,最少需要多少步。存在两种操作,第一种操作是讲一个数字转换为另一个数字,第二种操作是将一种数字转换为另一种数字。题解首先说明一下,这道题Uvalive是过不了的,只有Hihocoder能过。 这道题暴力BFS肯定是超时的。但是由于数字只有六种,我们可以考虑对数字种类转换进行BFS预处理。记录从123456-》123456到其他数字映射的最小步数,需要注意的是,原创 2017-10-01 16:20:27 · 295 阅读 · 0 评论 -
HDU 4804 轮廓线DP
题意给一个网格,里面能放1*1和1*2的方格,标记为0的地方不能放方格。问有多少种摆放方式。题解刘汝佳的训练指南上有这个的简化版本,在哪个版本中不存在1*1的方格和不能放置的方格。但是实际上,这种放方格的问题,无论有多少要求,轮廓线DP都能很好的解决。 深入理解轮廓线DP是解决这道题的前提条件,普通的状压DP是针对行来考虑的,而轮廓线DP是针对格子来考虑的。对行进行的考虑,只能依靠枚举两行的状态来原创 2017-10-09 22:15:58 · 308 阅读 · 0 评论 -
HihoCoder 1259 数位DP
题意3× f(n) × f(2n+1) = f(2n) × (1 + 3f(n)), f(2n) < 6×f(n).。要求每一个N满足这两个式子。设所有的f(n)%k==t为g(t),求所有g(t)的异或。题解首先我们需要发现f(2n)=3*f(n),f(2n+1)=3*f(n)+1。了解了这个以后,我们可以将一些数写出来,比如说1,3,4。。。如果我们把这些数写成二进制形式,可以发现,是按照二进制原创 2017-10-01 22:34:12 · 324 阅读 · 0 评论 -
HDU 4778 状压DP+博弈
题意给G种颜色,B种背包,每S种同一颜色的宝石可以合成一种神奇的宝石。A和B每次取一袋宝石到熔炉中,如果可以合成新的宝石,那么拿走这些宝石,并且可以再次拿一袋宝石到熔炉中。问A所得宝石-B所的宝石的最大值是多少?题解很好的一道题,状压DP融合了博弈的思想。首先我们要明确,博弈的最优状态是由最终的必胜态决定的,因此我们需要从最终状态向前转移。对于一个状态,如果这个状态该X取宝石了(X是谁无所谓),那么原创 2017-10-05 20:00:27 · 295 阅读 · 0 评论 -
HDU 4799 树形DP
题意微博投票,有两种投票选择方式,一种是选择LIKE,另一种是选择CANDLE。允许进行一些翻转操作,有一些点是已经被别人翻转过的,对于这些点我们翻转需要消耗Y的票数,对于其他的点我们翻转需要消耗X的票数。问我们最多可以得到LIKE-CANDLE票数最大值是多少。题解题目很难读,有很多坑。比如说给的投票状态是最初的状态,也就是别人还没有反转的状态,因此如果别人翻转了的话,我们还需要在DFS的过程中进原创 2017-10-05 22:26:14 · 301 阅读 · 0 评论 -
HDU 4433 DP
题意给1000个数字,每次可以转动1-3连续位,问从一个状态转到另一个状态最少需要多少步。题解比赛时候想复杂了,这道题跟BFS没有任何关系。不过还是有很多神牛用记忆化搜索过了。主要就是设计DP状态,网上有一种比较好想的状态,dp[i][j][k]代表第i个位置已经合法了,j代表第i+1个位置向上转动了j步,k代表第i+2个位置向上转动了k步。这样的话,我们就可以很轻松的进行状态转移。注意事项唯一需要原创 2017-10-12 13:27:46 · 274 阅读 · 0 评论 -
CFGym 101490D DP
题意有N条船,每条船过河需要20S,桥放下和拉起需要60S,要求使得桥放下之后的总时间最小,问这个最小的总时间题解想清楚了就发现很简单。。。 状态转移方程如下:dp[i]代表前i条船通过所需要的最少时间dp[i]=min(dp[i],dp[i-j]+max(a[i]-a[i-j+1]+20-1800,j*20)+120);对于一条船,这条船有可能是在前面某一条船把桥拉起的时候,没有放下,然后通过可原创 2017-10-15 16:02:49 · 320 阅读 · 0 评论 -
HDU 6006 状压DP
题意给最多10个任务,每个任务完成需要一些技能,给最多10个工程师,每个工程师拥有一些技能。每个工程师只能完成一项任务,问最多可以完成多少任务。题解看到数据量只有10就应该想到是状压DP的,对于这道题我们发现技能状态很多而拥有工程师的状态很少。(因为最多只有10个工程师)我们这时候就要意识到要对工程师进行处理。我们可以枚举一下对于每个任务,哪些工程师能解决问题,需要注意处理掉工程师数量大于3的状态(原创 2017-09-20 00:30:14 · 390 阅读 · 0 评论 -
SPOJ HKNAP 部分贪心
题意有S个袋子,袋子容量为Y,合并两个袋子花费为C,雕像有N种。接下来N行每行有一个W和一个V,分别代表雕像的重量和体积。问所带的雕像重量-袋子花费最多可以是多少。题解这道题是出现在部分贪心这篇OI论文中的。尽管主题是部分贪心,但实际上就是背包的空间优化。不过不是从算法上进行优化,而是从题目的信息上进行优化。 首先的话,根据题目体积只有1-18这18种情况,那么我们就只保留对于每个体积重量最大的元原创 2017-09-07 17:51:47 · 372 阅读 · 0 评论 -
ZOJ 3527 树形DP(章鱼图DP)
题意有N个村庄,每个村庄有一定的信仰值,占领村庄可以得到信仰值,每个村庄有一个关联村庄,同时占领关联村庄可以得到加成(可能为负),问占领一些村庄,最多可以得到多少信仰值题解这个DP已经不能算是树形DP了,因为有环。不过有趣的是环只有一个(可能有多个环,但是不可能存在环套环)。这样的话我们便可以破环进行DP。 如果画一下图的话可以发现这个图很像一只章鱼,我们进行DP的话,可以首先从触手的位置开始,我原创 2017-09-04 10:13:05 · 529 阅读 · 0 评论 -
CSU 1963 斜率DP
题意有N个点,M只兔子,P个饲养员。每只兔子都有一个出现时间,只有在出现时间之后喂食才是有效的。 一个饲养员从任意时间点从起点出发,每分钟走一步,不能停留。要求喂完所有的兔子,问兔子的最小等待时间总和。题解这道题非常适合用数形结合的思想去解决,CSU-1963 Feed the rabbit(斜率优化dp)这篇博文讲的非常好,非常新颖而且易懂。 我这里也讲一下自己的理解吧,因为有两个量,时间和距离原创 2017-08-26 10:22:41 · 234 阅读 · 0 评论 -
POJ 2486 树形DP+背包
题意一棵树,树上有N个点,能走K步。第二行有N个数字,代表着N个点上的苹果数。后面N-1行代表苹果树的联通情况。问最多能得到多少个苹果。题解又是一道树形DP的题目,不过这道题不太好搞。这道题涉及的情况还是比较复杂的,需要十分缜密的思维。首先我们可以把状态转移方程设置为dp[i][j][k],i代表当前点,j代表当前状态还可走的步数,k分两种状态,0代表回到当前点,1代表不回到当前点。 对于回到当前原创 2017-08-23 10:51:57 · 272 阅读 · 0 评论 -
HDU 3183 贪心
题意给一堆数字,从中删去M个数字并且去掉前导零以后,要求形成的数字最小,问形成的最小数字是多少。题解其实是很水的贪心题?好像可以用RMQ进一步优化,不过使用普通的贪心算法就可以达到一个不错的时间。贪心方法很简单,持续选择x[i]>x[i+1]的就可以了。这个是可以证明的,如果删掉i前面的任何一个数字,数字的总位数只会减少一位(其实也可以相当于后面的数字进了一位),这样形成的数字一定不如删掉i更划算。原创 2017-08-23 14:31:57 · 244 阅读 · 0 评论 -
Gym 101485D 记忆化搜索
题意有N行代码,有1个BUG,可以在行之间输出信息,编写输出信息需要时间,运行需要时间。假设找到BUG是在最坏的情况下,问最少需要多少时间才能找到BUG。题解对于大于一行的代码,我们也不知道怎么输出多少信息才能最快找到BUG,索性暴力吧。暴力枚举将代码分成2-N块的情况,记忆化搜索一下,选择找到BUG的最小时间,输出就可以了。代码#include <iostream>#include<cstdio原创 2017-09-05 20:14:32 · 542 阅读 · 0 评论 -
HDU 3586 树形DP
题意1号点为总司令点,叶子节点为士兵点,要求所有士兵点不能接受到总司令的指令。剪断一条线路有花费,总花费不能超过M,单次花费上限不能超过limit,问limit最小为多少。题解首先分析题目,题目中提到了四个状态,点,单次花费,总花费,剪断方式。首先的话,我们可以分析,花费由于数据范围很大,所以是不能作为动态规划的状态的,我们考虑用二分去枚举单次花费,总花费我们考虑作为DP的结果,如果总花费大于花费上原创 2017-09-14 15:17:30 · 253 阅读 · 0 评论 -
HDU 2415 树形DP
题意有N个国家,我们要获得M个国家的选票,我们可以贿赂一些国家。如果贿赂一个国家的统治国家,那么它统治的所有国家的选票都可以获得。贿赂一个国家需要一些钻石,问最少需要多少个钻石。题解其实是比较容易想的,只是数据格式好坑啊。这里强烈推荐一个函数。sscanf(ch,"%d%d",&n,&m);这个函数可以按一定格式读取一个字符串。做这道题可以方便一些。 我用的是strtok,一个字符串分割函数,也可原创 2017-09-14 22:00:57 · 359 阅读 · 0 评论