自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

AC_Arthur的专栏

Always challenge miracles!

  • 博客(46)
  • 收藏
  • 关注

原创 12034 - Race(递推)

搞了快一个月的高效和动归了, 太费脑子,水一道数学~ 该题是递推题,动归没白搞,很快就写出来了 。 现在有点明白为什么比赛要测试栈深了,递归的应用实在是太多了 。一般对某数取模是因为答案太大会爆long long  , 至于为什么要对这么奇怪的一个数取模,好像是因为这样答案离散的比较好?有清楚的朋友希望不吝赐教 !代码如下: #includeusing namespace std

2015-07-28 18:50:55 683

原创 10163 - Storage Keepers(DP)

该题乍看好像背包问题,但是实际上实现起来就会发现细节上还是很不同的,  这小小的不同就可能导致完全错误,所以有必要对具体的推理过程进行归纳总结,以期找到动态规划的通用思路 。首先,我们应该先完全明确状态方程表示的含义 。 对于该题,设d[i][j]表示i个守卫,看守j个仓库的最小安全系数的最大值 。其实说的简单一点,它就表示最小安全系数 。一定要明确这一点,才能写出正确的递推关系 。  

2015-07-28 16:59:12 682

原创 1632 - Alibaba(DP)

该题过的人不多,但是实际上并不难 。首先,不难用贪心的方法证明,起点一定要选最快消失的点, 所有宝藏地点的坐标从小到大排列,因为起点固定且获取宝藏的时间忽略不计,所以不难发现任意时刻,已经拾取的点一定是一个连续的区间, 因此可以用d[i][j][k]表示拾取完(i,j),且当前在位置k(k=0表示在i点,k=1表示在j点) 。怎么样? 是不是很眼熟?对,该题和例题 《修缮长城》几乎一模一样,

2015-07-28 09:52:42 704

原创 1612 - Guess(贪心)

该题的思路很好想,就是尽量取大一些的成绩为后面的人留出更大的 “空间” 。   细节也很好想,这里不再赘述,值得一提的是 : 该题存在精度问题 , 导致我一开始一直WA。由于输入和输出只保留两位小数,所以我们不妨将浮点数变成小数,这里要用到round函数,将不需要的小数位四舍五入到整数 。#includeusing namespace std;const int maxn = 1638

2015-07-28 08:11:40 752

原创 1614 - Hell on the Markets(贪心)

n很大,不能DP甚至nlogn都有可能超时,令我不得不想到了贪心。。。结果贪心

2015-07-27 14:20:34 1010

原创 1611 - Crane(贪心)

该题刘汝佳给了提示:2n次操作就足够了 。 为什么呢? 题目只允许一种操作:选一个长度为偶数的连续区间,交换前一半和后一半 。  对待区间排序问题,贪心法通常怎么用? 对,还记得这章习题《外星人聚会》吗 ? 我们贪心的将当前位置的数安置好就可以了 。那么这样最多需要多少次操作呢? 就是2n次。 对于每一个数,我们想把它安排到它应该在的位置,最多只要2次操作 。 那么我们就可以分情况讨论:

2015-07-27 09:18:13 839

原创 10570 - Meeting with Al (贪心)

一开始我妄想在O(n)的时间内求出答案,但是后来证明我的方法是错误的,这里就不再赘述了 。网上提供的一种方法是枚举起点,然后使得从起点开始的每一位都对应着是1、2、3...n 或者相反 。 如果不是,将对应的值交换过去 。这显然是一种贪心策略 。  不断追求局部最优,最后的答案也是最优 。证明贪心的方法一般是反证法 :  假设这样不是最优,那么当前这个数要和其他的数交换几次后再换到这个

2015-07-25 10:43:42 1085

原创 11925 - Generating Permutations

乍看该题似乎无法下手,但是我们注意到题目所给的操作次数非常大, 而且看它的两个操作,是不是感觉很熟悉? 没错,冒泡排序的复杂度正是O(n^2) 。该题正是冒泡排序的改进版 。   但是题目要求我们的是将一个1~n的升序序列变成给定序列,这是不好操作的,我们不妨用逆思维来想,由所给序列变成升序排列应该也是可行的。 但是问题在于操作只有两个,是规定好的,那么我们相应的也要变一下,将操作2变成从队列

2015-07-24 21:53:51 754

原创 177 - Paper Folding (找规律)

一开始看这题感觉无从下手,甚至一开始根本没理解题意 。后来明白了,是一张纸,每次都是从右向左折叠,注意折叠后不要动 。折叠完n次后,最底下那一个纸条要保持原位置不动(水平放置),其他的按题目要求展开,从侧面就会看到一条连续的“美丽”曲线 。那么怎么样找到这条曲线呢? 其实是有规律可循的 。我们把边看作路径,那么行走的方向命令就可以写出了 。 如下:n = 1 --> run = 2

2015-07-24 12:04:02 1675

原创 1610 - Party Games(细节题)

不知道为什么把这道题放在高效里,我这一点也不高效的方法居然也跑了0.016s我们需要做的很简单,挨个字符的选择,然后先加上这个字符,和所有字符串比较一遍,根据大于它和小于它的字符串个数进行判断就好了 。  注意z这个字符 ,对于某些数据,会TLE的。。。没什么意思,直接看代码吧:#includeusing namespace std;const int maxn = 10000 +

2015-07-22 21:38:21 851

原创 1442 - Cav

该题非常巧妙,题意大概是,要像一个洞穴里填装液体燃料,但是洞穴顶上有电线,不能让液体触碰到,但可以无限接近顶 。 求最大存储的液体体积 。这样就相当于求任意一点i ,使得从该点向左向右延伸都不会碰到天花板 , 的最大高度 。  显然该题的n比较大,我们不能用最常规的思路来解决。 向左向右延伸出的两条射线均不能碰到天花板 , 所以我们不妨将问题分解,先求出从左向右可以延伸的最好情况,再从右向左,

2015-07-21 19:47:36 756

原创 1619 - Feel Good(高效算法-利用数据结构优化-优先队列)

该题我跑了0.251s,名列第三。。第一第二比我这个优化了好多,真不知道怎么弄的 ,感觉已经无法优化了 。我认为该题的正解是紫书上P241页所讲的内容,即维护一个单调队列,动态维护求出每个数以它为最小值的最大区间 。 只需要O(n)的复杂度 。怎么样?很神奇吧 !   该题的难点就在于求区间最小值, 所以这个方法再适合不过了 。下面我将详细讲解一下:说起来也简单,大家可以出一组数据,按

2015-07-20 21:33:38 1080

原创 1336 - Fixing the Great Wall(DP)

本题极为经典,是动态规划中“未来费用”的计算, 因为起点固定且维修时间忽略,所以任意时间已经修复的点一定是一个连续的区间 。因此我们用d[i][j][k]表示已经修理完区间[i,j]且现在正在点k ,如果k为0,在i点,如果k为1,在j点。这显然已经可以表示所有状态,那么怎么维护时间这个量呢?  我们可以发现,每过t时间,没有维修的点都将增加费用,所以我们不妨先预处理求出每个区间的d值只和,然

2015-07-20 19:03:05 1625

原创 10559 - Blocks(方块消除|DP)

该题乍一看和矩阵链乘很相似,可是有一个不同之处就是该题可以拼接 。   为了达到这个目的,我们不得不拓展维度d[i][j][k],用一个k表示最右边拼接了k个和a[j]相同颜色的方块。问题的关键在于拼接,当右边存在一个q 细节见代码:#includeusing namespace std;const int maxn = 205;int t,n,d[maxn][maxn][max

2015-07-19 17:04:07 1669

原创 10934 - Dropping water balloons(DP)

这道题的思路很难想。 问你需要的最少实验次数,这是很难求解的,而且我们知道的条件只有三个,k、n、实验次数 。所以我们不妨改变思路,转而求最高所能确定的楼层数 。  那么用d[i][j]表示用i个球,实验j次所能确定的最高楼层数 。那么我们假设第j次实验是在k楼,有两种可能: 1、球破了,那么状态如何转移? 用了一个球,用了一次实验机会,所以最优情况一定是从d[i-1][j-1]转移过来的

2015-07-19 11:15:01 1193

原创 10723 - Cyborg Genes(LCS)

该题实际上就是LCS的变形,所要求的最短合成串长度其实就是两串相加再减去LCS的长度 。  很好理解,因为合成串中一定要包含LCS中的元素,然后非LCS的元素都要加进去,这样两串相加就多了一个LCS 。 所以答案就是len1 + len2 - len_LCS 然而该题的难点是求最优解的个数 。 显然,由于合成串中一定要有LCS,因此,解的个数的求解和刚才完成的dp有着千丝万缕的联系 。

2015-07-18 20:31:59 909

原创 1629 - Cake slicing(DP)

花了近2个小时最终AC,好爽。。一道类似于最优矩阵链乘的题目,受《切木棍》那道题的启发,该题的原理也是一样的,只不过变成了且面积,那么相应的也要增加维度 。显然要完整的表示状态,最少要用四维数组,分别表示它的两个对角线顶点的坐标 。   然后横切或者纵切,递归需找更小的矩形,直到矩形内只剩一个樱桃的时候返回0那么问题就是怎样快速的判断一个矩形内有多少个樱桃,于是决定再开一个数组记录这个矩形

2015-07-18 10:11:19 837

原创 10118 - Free Candies(DP)

自己想出来的,一遍AC,0.132s说说我的思路吧,首先考虑如何表示状态,不难发现,情况非常多,因为怎么拿都行,所以只好增加维度,开四维数组。由于结构比较无序,所以选择了记忆化搜索 ,受前面《校长的烦恼》的启发,即使我们还要维护篮子中糖果情况,但是我们只需开四维数组就已经足够表示所有的状态了 ,我们大可以将篮子中的情况以及口篮子中糖果的数量放在函数的参数中来维护就可以了,那么我们不难用d[

2015-07-17 21:58:30 841

原创 10285 - Longest Run on a Snowboard(DP)

比较简单的DP,用记忆化搜索比较简单,递推。。。应该不好写吧 。  很容易发现,对于同一个位置,它的最长路是一定的, 不会变的,因为路是递减的,所以该题很适合用记忆化搜索 。  由此我们也可以发现DP和搜索的联系 。代码如下:#includeusing namespace std;int T,r,c,a[105][105],d[105][105];int dx[] = {0,1,

2015-07-17 20:42:26 961

原创 1252 - Twenty Questions(状态压缩DP)

经典的状态压缩DP 。  有没有感觉这道题和什么东西有点像?  没错,是01背包 。 将特征看作物品 , 只不过这里的状态有点复杂, 需要用一个集合才能表示它, 所以我们用d[s][a]来表示,已经询问了特征集s , 假设我们要猜的物品是w ,w所具备的特征集为a ,此时还要询问的最小次数 。   显然a是s的子集,而且要注意本题的要求, 求的是最小化的最大询问次数 。也就是说无论猜哪个物品,猜这

2015-07-17 19:17:38 817

原创 各种操作符及其优先级

优先级运算符名称或含义使用形式结合方向说明1[]数组下标数组名[整型表达式]左到右 ()圆括号(表达式)/函数名(形参表) .成员选择(对象)对象.成员名 

2015-07-15 20:36:31 1340

原创 10817 - Headmaster's Headache(校长的烦恼)

经典的状态压缩DP 。根据DP的阶段定义,我们需要枚举每一个教师进行递推,但是由于每个教师可以教授的课程是复杂多样的,所以使得状态变得难以转移 。那么要怎么样表示状态呢? 显然增加一两个维度是无法胜任的,所以我们可以用二进制枚举子集的方法,用一个整数通过位运算充当一个集合 。 C++提供的位运算符极像对集合的操作,我们恰好可以利用这一点 。用d[i][s1][s2]表示考虑了前i个人时的最

2015-07-15 20:01:40 1159

原创 1218 - Perfect Service(完美服务)

这是一道经典的树形DP题目,特点是要优化状态 。仔细思考为什么要将状态定义成紫书上说的那样,因为该题要求每台不是服务器的计算机恰好要和一台服务器计算机相邻,  然而如何由当前节点看出来这点呢? 如果只是看他的子节点显然是不够的,因为他的父节点也对这个条件起至关重要的影响 。  所以才要维护三种情况来将状态的转移弄清楚。由于是自顶向下递归,如果u是服务器,那么子节点可以是服务器也可以不是 ;

2015-07-14 21:44:39 1596

原创 1220 - Party at Hali-Bula(Hali-Bula 的晚会)

树形DP 。 因为不能同时选择一个人和他的直属上司 , 所以需要维护两个值d[u][0]表示不选该节点,d[u][1]表示选择该节点 。   当然,题目还有一个要求,那就是判断解的唯一性, 所以再添加一个数组维护唯一性。  我们不妨分别分析  :  1.d[u][1]的计算 , d[u][1] = sum{d[v][0]} + 1; v是u的子节点,因为要依赖所有子节点的解,所以当且仅当所有f[v

2015-07-14 19:17:11 1162

原创 1331 - Minimax Triangulation(DP)

该题就是最优三角形剖分的变形,虽然要用到一些几何知识,但是我们可以将其区间化,让决策变得有序 。  这样就变成了区间问题 。  我们定义d[i][j]表示由i~j顶点组成的子多边形的最优解,那么不难写出状态方程 : d[i][j] = min(max(d[i][k],d[k][j],S)) 其中S为i、k、j三个顶点构成的三角形面积。 我们不难发现这样的递推是正确的,但是有一个问题:我们划分出的图

2015-07-12 20:50:07 865

原创 判断点P是否在三角形ABC内

已知:三角形ABC,点P问题:点P是否在三角形内1.面积法    如果三角形PAB、PAC和PBC的面积之和与三角形ABC的面积相等,则可判定点P在三角形ABC内(包括在三条边上)。已知三角形顶点A、B、C)的坐标分别为(Ax, Ay)、(Bx, By)、(Cx, Cy),即可计算其面积:     S = |(Ax * By + Bx * Cy + Cx * Z

2015-07-12 20:48:14 1970

原创 1626 - Brackets sequence(DP)

和前面一样,要注意状态的枚举顺序,边界是d[i+1][i] = 0 和d[i][i] = 1  ,所以枚举的区间应该从小到大,大区间依赖于小区间的最优解 。然后就是状态的转移,是如何转移的呢? d[i][j]表示字符串i~j的最优解,那么先检查i与j是否匹配,如果匹配,状态转移可以转移到d[i+1][j-1] 。 无论是否匹配,状态还都能转移到子区间上:d[i][k] 和 d[k+1][j]

2015-07-12 16:13:35 761

原创 10003 - Cutting Sticks(DP)

类似于最优矩阵链乘,将长区间划分成段区间求解,换句话说:长区间依赖于段区间 。 因此如果利用二重循环递推的话,枚举的顺序应该是木棍的长度从小到大,因为长区间依赖于短区间的最优解 。 所以动态规划的重点我认为就是对状态的定义和动态规划的方向,  状态的定义要确保覆盖所有状态,规划的方向要遵循一个状态依赖于另一个早已解决的状态。     所以该题有两种解决方法:记忆化搜索和递推 。我分别用这两种方

2015-07-12 11:14:45 874

原创 ACM常见问题1

取模:取模运算n%p的结果与p的符号无关,由n决定。例如:7%4=3,-7%4=-3,7%-4=3,-7%-4=-3;基本的运算:(a+b)%p=(a%p+b%p)%p(a-b)%p=(a%p-b%p)%p(a*b)%p=(a%p*b%p)%p(a^b)%p=((a%p)^b)%p///////////////////////////

2015-07-12 10:07:29 799

原创 11584 - Partitioning by Palindromes(DP)

和上一题 “照明系统设计”类似,我们可以逐步递推出最优解,d[i] 表示1~i个字符的最优解,那么d[i] = min(d[i],d[j] + 1)|当s[j+1~i]为回文串时。大家可以自行打印d这个数组,来体会一下状态的转移情况。代码如下:#includeusing namespace std;const int maxn = 1000 + 10;const int INF

2015-07-11 16:12:39 1244

原创 11400 - Lighting System Design(DP)

该题以电压v,使得枚举有序化,对于每一种灯泡,怎么判断是不是要用它呢? 如何形成递推呢?我们知道,递推就是要用到之前早已存好的值来确定当前最优解,所以我们用d[i]表示用1~i种灯泡的最小费用。由于每种灯泡要么使用,要么被别的灯泡替代,所以d[i] = min(d[i],d[j] + (s[i]-s[j])*a[i].c + a[i].k);   其中j 由于第n个灯泡电压最高,无法被

2015-07-11 11:57:17 943

原创 12563 - Jin Ge Jin Qu hao(DP)

自己花了两个小时A出来的感觉就是不一样啊,学习DP建议大家多煎熬一点,好好思考状态是如何转移的。不过这道题我一开始理解错题意了,不然也不会浪费这么长时间 。 一开始以为是背包问题,后来才发现要求使得唱的曲目尽量多,在此前提下尽量晚离开KTV,我恰好弄颠倒了。这样我们就不难得出递推方程 : 因为每首曲目只能唱一遍,所以这就使递推变得有序了~ 那么我们设cnt[i][j]表示唱前i首歌中的若干

2015-07-11 11:13:20 1869

原创 1347 - Tour(DP)

题意:给定平面上n个点的坐标,设计一条路线,从最左边的点出发,走到最右边的点再返回,要求除了最左点和最右点之外每个点恰好经过一次,问最短路径。典型的多决策问题,需要用DP解决,关键是每个点恰走一次,所以需要将使DP有序化,因此我们规定d[i][j]表示1~max(i,j)全走过,且当前两人位置是i和j,还需要走多长的距离。因为这两个人是无所谓的,所以d[i][j] = d[j][i] 。因

2015-07-11 08:33:25 1265

原创 116 - Unidirectional TSP(DP)

多段图的最短路问题 。  运用了很多的技巧 :如 记录字典序最小路径 。细节参见代码:#includeusing namespace std;const int INF = 2000000000;int m,n,a[15][105],d[15][105],next_[15][105];int main() { while(~scanf("%d%d",&m,&n)) {

2015-07-10 21:14:31 966

原创 437 - The Tower of Babylon(记录结果再利用DP)

最近准备进入动态规划的章节,仔细看了看紫书上对01背包的讲解,感觉很好。。之前看《挑战程序设计竞赛》那本书,就没有讲的那么深刻 。      更加深刻的理解了什么叫记录结果再利用,手工操作了一遍01背包的过程,也有点明白它的状态是如何转移的了,而且那个状态方程所构成的递推关系真的很巧妙 。言归正传。。这道题就是嵌套矩形问题稍微改了一下,之前的嵌套矩形只需要维护一个状态量就行了,但是这道题是立方

2015-07-10 20:23:37 994

原创 1618 - Weak Key

一开始自己搞,写了半天还是成了四重循环,虽然没个循环依次递减,而且二分查找,但是依然超时,唉,看来还是太弱啊,思路过于单一。搜了一个题解,是用递推构造了两个二维数组,利用题目的特点维护了两个变量,然后只需要枚举q和r就可以了。l[i][j]表示下标小于j且值比a[i]大的数中最小的值的下标。 r[i][j]表示下标大于j且值比a[i]小的数中最大的值的下标。我们枚举q和r ,那么显然可

2015-07-09 20:45:23 2039

原创 1153 - Keep the Customer Satisfied(贪心)

又是一道经典的贪心算法题目 。 乍看题目,想到了紫书一开始讲的区间问题(给定一些区间,选择尽可能多的不相交区间),和另一个经典问题:“活动安排”  的实质是一样的。但是本题又和区间问题不同,因为区间起点未知,我们所知道的仅仅是等待时间和截至时间,但是其实贪心思想是一致的,即:尽可能的给后面的人留下更多时间,满足当前所用时间最少。 因此可以写出贪心算法 : 按照截至时间排序,将元素的消耗时间加到

2015-07-08 19:41:05 1010

原创 12545 - Bits Equalizer(贪心?)

这道题我是自己出的思路,一遍A的 ,0.000ms。 看网上的题解大多相仿,我就说说我的思路吧 。假设字符串 a、b我们只需要从前向后扫一遍就行了,遇到?跳过去,遇到a[i] = '0'&&a[i]!=b[i] ;那么就向后找一个a[j]=='1'&&a[i]!=b[j],也就是说先用交换这个技能比较省步骤 。如果没有可以交换的,再扫一遍找? 如果a[i]==? && b[i]==0  那

2015-07-07 20:03:24 828

原创 11491 - Erasing and Winning(贪心)

一开始真的没想到这竟然是一道贪心题目。  不过后来仔细想想也就明白了。我采取的做法是自前向后扫一遍,用一个指针rear动态维护答案数组中的最后一个元素,如果遇到一个比它大的数s[i],那么从它开始将它及其它之前的比s[i]小的数全部删除,并且用变量cnt记录删除的个数, 防止删除多了。对于贪心算法的正确性我们不难用反证法来证明: 假设这样做不是最优的,那么如果不这样做,对于一个长度一定的答

2015-07-07 18:55:08 1369 1

原创 1451 - Average(数形结合)

该题表面让我们求一个字符串的问题,但是却可以转化成求斜率的问题, 紫书上已经说的很清楚了,我这里就不再赘述  。代码如下 :#includeusing namespace std;const int maxn = 100000 + 5;int n,T,L;double a[maxn],p[maxn];char s[maxn];int campare(int x1,int x2,

2015-07-06 19:16:59 1245 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除