摘要: 以前也碰到过这种类型的题目,以前好像做出来过,但是忘记了,这次又坑了。题目很简单,对于从前到后每一个连续的长度为k的数字,求出这段数字中的最大的数字和最小的数字。一开始我用离散化+树状数组来更新和查询,时间复杂度为n*log(n)*log(n)。这尼玛果断T啊。后来才发现,没那么复杂哦。其实是用一个优先队列来解决问题的。什么意思呢?对于初始状态,我们可以加入k-1个元素,然后每次加一个元素,进行弹出和查询的操作。首先我们创建两个队列,分别用来解决最大值和最小值的问题。这里只需要说明一下最小值的队列就可以了,最大值队列同理。假如当前我们要加入一个新的元素x,我们只需要将x与队尾的元素进行比较,如 阅读全文
posted @ 2013-11-11 21:17 092000 阅读(242) 评论(0) 推荐(0) 编辑
摘要: 这个题目很有意思,也是一个很好的题目,涉及的知识点比较广,要求较高。题目是这样的,给定你一个n个数的数列,问你有多少个长度为5的上升序列。首先看到有50000,我们就知道肯定不会是DP。(但是不知道为什么我居然在DP优化这个章节里面做到了这个题)由于给的数是在int范围里面的,我们需要首先将其离散化,这样相当于每个数的范围只有5000了。剩下的就是这个题目的最最精华的地方了。其实这里的统计是用树状数组来实现的。但是不是单单由一个树状数组实现的,而是5个。什么意思呢?我们用f[i][j]表示不大于j的长度为i的上升序列有多少个。这样就是一个递推了哦。而对于每一个查询我们都是通过树状数组来实现的, 阅读全文
posted @ 2013-11-10 17:24 092000 阅读(446) 评论(0) 推荐(0) 编辑
摘要: 题意是描述是这样的,给你n个围栏,对于每个围栏你必须走到其边上才可以往下跳,现在问你从初始最高位置的n个围栏,到原点,水平走过的路程最少是多少?其实我可可以这样来考虑问题。由于每次都是从板子的左右两端往下面跳,我们可以从1到n有序的加入每一块板子(相当于对区间染色),加入每块板子查询一下它的两端的下面的点是什么。有了这个操作我们就可以直接预处理出来从每一块板子左右两端跳下来会落在那一块板子上面。那应该用什么办法来实现这个查询和更新呢?显然,线段树。下面我们等于是分别从第n块板子的左右端点往下走,然后求到原点的水平最短路了,直接一遍SPFA搞定。上代码吧,下面省略若干个字。 1 #includ. 阅读全文
posted @ 2013-11-10 17:14 092000 阅读(699) 评论(0) 推荐(2) 编辑
摘要: 题意很简单,给你若干个数字,你需要减去一些数字,使得在数列中的每个数字出现的次数不少于k次。一开始我们都会想到是用DP,于是很快我们就可以得出状态为搞定前面i个数所需要花费的最小代价用f[i]表示。接下来我们可以得到状态转移方程为f[i]=min(f[j]+sum[i]-sum[j]-(i-j)*a[j+1]);j的枚举范围为k到i-k。这是很容易理解的。但是再看题目我们就会发现这个算法的时间复杂度为O(N^2),题目中N多大500000,根本无法承受。所以需要优化的说。接下来要说的就是优化了,这个叫做斜率优化的说。我们假设当前要求f[i],那么对于前面的任意两个j1和j2(j1i*(a[j1 阅读全文
posted @ 2013-11-07 21:17 092000 阅读(680) 评论(0) 推荐(1) 编辑
摘要: 很有意思,很好的一个题目。题目的意思是两个人初始状态分别有A和B元,现在有N件可买的商品。两人轮流买,商品必须从左到右买过去,一次可以买若干个。第一个无法买到商品的人输。一看就知道是博弈题目,但是这并不是什么模型式的博弈题目,其实是转化成递推来做的。一开始我也不知道到底应该怎么来考虑这个问题,于是就按照博弈的思想用Mex的思路去写这个题目,直到我T了发。后来在网上看到神牛们写的博客后才发现正确的解法。其实这个问题应该是这样来考虑的。首先告诉了你两个人初始的钱数,那么总共的钱数是确定。在买完若干件商品后,一部分的钱数已经花在了买商品上面(先不管是谁买的),另一部分的钱还分别留在两个人的手中。这样 阅读全文
posted @ 2013-11-05 11:13 092000 阅读(2389) 评论(1) 推荐(1) 编辑
摘要: 这是一个很好的题目,来自2013长春网赛。题目的意思是给你2^N张扑克牌,每次洗牌前分别把从下开始数为奇数和偶数的牌分别拿出来放在一堆,两堆可以任意一个放在上面。现在问你是否存在一种情况使得经过若干次洗牌后,第A张牌的编号为x,且同时第B张牌的编号为y。(初始状态从低到顶编号从1递增)题目的解法是用二进制来模拟洗牌的过程,然后发现洗牌的规律为右移+异或操作,然后就可以解决了。但其实本题最最难以想到的是,题目给你的牌的编号是从1开始的,然而为了方便地使用二进制,我们需要从0开始编号。首先对于每一个牌,我们都先把其编号减一,相当于从0开始编号,这样对于读入的四个数,我们都将其减一就可以了。然后我们 阅读全文
posted @ 2013-11-02 17:02 092000 阅读(681) 评论(0) 推荐(0) 编辑
摘要: 题意很简单,要你用一些数字,组成一个数的倍数,且那个数最小。比赛的时候没能做出来,深坑啊。其实我只想说我以前就做过这种类型的题目了,诶。题目的解法是数位宽搜。首先把可用的数位提取出来,从小到大一个一个放到后面去。这样保证了出现的数字一定是最小的。同时记录出现过的余数的情况,因为同一个余数k*10+ai再对n取余的数是相同的,所以对于同一个余数我们不需要走两遍,这样就保证了搜索的时间复杂度为O(n)。我们只要对于每一个状态,直接枚举可选择的数字放在他们后面,直到找到一个余数为0的就可以停止了。总的时间复杂度为O(n*10),因为后面最多可能有10个数可以放上面嘛。。。。对于深搜的每一个状态只要用 阅读全文
posted @ 2013-11-01 20:12 092000 阅读(324) 评论(0) 推荐(0) 编辑
摘要: 很考验智商的一个题目,赛后看完别人的题解后秒懂了。首先定义一个函数f(x)表示a,b的有序组合情况数使得a*b为x的一个约数。现在给定你一个n,要你求出f(1)+f(2)+……+f(n);题目智商味道太浓厚,本屌表示智商拙计。可以这样来考虑问题,a*b为x的一个约数,其实就等价于a*b*c=x,c为任意一个正整数。所以整个问题转化为有多少个有序数对(a,b,c)使得a*b*c不大于n。到这里问题就变得好办多了。由于直接枚举复杂度过高,我们在枚举的时候可以假定a 2 using namespace std; 3 typedef long long ll; 4 ll n,m,k,ans,i,j; 阅读全文
posted @ 2013-10-31 09:03 092000 阅读(250) 评论(0) 推荐(0) 编辑
摘要: 题目的意思简单,给你n个点,每个点(除根节点)都有且只有一个父节点。现在问你这些节点关系组成的图有多少种情况满足同一层节点上每个点的后继节点数量相等。很简单,对于n节点,直接枚举n-1的的所有约数情况,可以用记忆化搜索,直接递推也可以。Easy problems . 1 #include 2 #include 3 #define maxn 1010 4 #define M 1000000007 5 using namespace std; 6 typedef long long ll; 7 8 ll f[maxn]; 9 int n,k=0;10 11 int main()12 {13 ... 阅读全文
posted @ 2013-10-30 21:51 092000 阅读(168) 评论(0) 推荐(0) 编辑
摘要: 今天比赛做的一个题目,不过今天终于感受到了复旦题目有多坑了。题目的意思是给你一段长为n个单位长度的直线,你可以选择任意连续单位长度的线段组成三角形,可以组成任意你可以组成任意多个三角形,且要求其中所有的三角形相似。现在要你求出,总共有多少种三角形的情况。 详情见题目。题目的意思明白了以后就可以开始思考具体怎么解题了。比赛开始的时候我也很费解,到底怎么求出所有的排列组合的情况。一开始我是这样考虑的,要使得最终的每一个三角形都相似,那么其中所有的三角形必须有一个不小于3的公约数,但是对于三角形的边长怎么不重复地搞出来还是没有办法。其实是这样来搞的。我们用一个函数f(i)来表示周长为i的独特的三角形 阅读全文
posted @ 2013-10-30 21:49 092000 阅读(408) 评论(0) 推荐(0) 编辑