12 2012 档案

摘要:题目链接:http://poj.org/problem?id=2299 给你一个升序列,然后要你只能交换相邻的两个数把这个序列按升序排列,求最少需要交换多少次。 不管怎么样,只要存在ai>aj(i<j),那么这两个数之间必须要交换。任意两个数不影响其它数之间的大小位置关系,所以可以看出就是求逆序对数量。求逆序对数量有很多方法,树状数组或者线段树优化等,但是用合并排序的方法更方便,即在合并左儿子和右儿子的时候,统计左儿子比右儿子大的数的个数即可,复杂度O(log(n))。合并排序版: 1 //STATUS:C++_AC_391MS_3688KB 2 #include<stdio 阅读全文
posted @ 2012-12-29 11:30 zhsl 阅读(334) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=1226 买一送一的题目,稍微修改POJ3450或POJ3080的代码就可以了。不过C++和G++不支持strrev()函数,因为strrev()不是ANSI C的语法,改为_strrev()就可以了。 1 //STATUS:C++_AC_0MS_172KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #incl 阅读全文
posted @ 2012-12-29 11:14 zhsl 阅读(206) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=3450 和POJ3080一个意思,都是要你求在n个字符串中,相同字串最长的一个。方法也是KMP+枚举,不过这题的数据大一点。 1 //STATUS:C++_AC_516MS_380KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algo 阅读全文
posted @ 2012-12-28 20:28 zhsl 阅读(239) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=3080 每个字符串的长度为60,而且字符串的数量很少,容易想到枚举水过。这题目的数据,就算纯暴力不优化,貌似也能过。加个KMP匹配也看不出多少优势。。。我在写KMP的时候,犯了一个低级的错误,居然把匹配过程写错了,导致wa了很久,下次吸取教训!!! 1 //STATUS:C++_AC_0MS_164KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include 阅读全文
posted @ 2012-12-28 20:24 zhsl 阅读(235) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=1035 方法很多,hash标记判重也可以,然后就是分情况判断就可以了。。 1 //STATUS:C++_AC_360MS_1132KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<v 阅读全文
posted @ 2012-12-28 20:18 zhsl 阅读(298) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=3436 题目噼里啪啦说了一大堆= =,其实很简单。对每个点拆点u-v,然后加限制容量,如果两个点之间可行,那么加边,容量INF,最后加源点s和汇点t,建立有向图后,求大流。只是这个题目的建图有点麻烦,果断用3进制优化后,内存减少了很多,处理上也方便了很多。 1 //STATUS:C++_AC_0MS_180KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #inc 阅读全文
posted @ 2012-12-27 00:38 zhsl 阅读(197) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=3020 大意就是,给你一张图,图中某些地方标记为‘*’,要你用1*2的圈覆盖所有的‘*',圈之间可以重叠,要求使得圈的数目最少。 开始我想的是状态压缩DP,后来发现复杂度有点高,以为会TLE。看了Discuss才知道正解是用最大独立集做,即在图上构造一张二分图,然后相邻的’*‘建立边关系,求最大独立集就可以了。至于算法的正确性,我们把独立的点和与之相邻的未盖点看做一个圈就可以了,如果少了一个独立的点,那么’*‘就会覆盖不完全,所以最大独立集就是最少的圈数。 1 //STATUS:G++_AC_0MS_908KB 2 #in 阅读全文
posted @ 2012-12-27 00:29 zhsl 阅读(381) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=1860 题目大意就是判断一个有向图中的是否存在正权环。利用Bellman-ford判断负环的思想,改为求最长路,如果在n-1次后再来一次bellman,如果还能更新,那么就是存在正权环。SPFA: 1 //STATUS:G++_AC_0MS_728KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #includ 阅读全文
posted @ 2012-12-27 00:17 zhsl 阅读(224) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=1573 随便模拟,水水~ 1 //STATUS:G++_AC_0MS_696KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector>10 #include<que 阅读全文
posted @ 2012-12-27 00:09 zhsl 阅读(214) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=3928 题目大意是:有n个人按顺序住在一条街上,给定每个人的乒乓球的技术水平值。现在他们要切磋球技,两两切磋,需要找一名裁判,这名裁判的球技水平必须在他们之间,而且他必须居住在他们之间。问一共有多少种情况。 如果直接枚举任意两个数,复杂度O(n^2),此题数据达到20000,铁定TLE。我们可以反过来枚举裁判,那么只要O(n)。接下来就是在[0,i-1]比num[i]小的数的个数,这里是关键,直接遍历的话也会TLE。这里并没有要求动态访问,只要求出结果即可,因此可以离线操作,用线段树优化。具体做法就是,从0开始遍历数列,依... 阅读全文
posted @ 2012-12-27 00:05 zhsl 阅读(356) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=2632 模拟水题,直接循环判定即可。 1 //STATUS:C++_AC_0MS_212KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector>10 #include& 阅读全文
posted @ 2012-12-26 20:44 zhsl 阅读(188) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=2027 大水题,不说了,纯属增加POJ题量。 1 //STATUS:C++_AC_0MS_164KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector>10 #incl 阅读全文
posted @ 2012-12-22 16:02 zhsl 阅读(211) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=2785 强烈鄙视自己啊,开始以为数据简单,结果用map标记一下,TLE了,然后改成动态化的hash,结果还是TLE!后来无奈改成静态化的hash才AC!至于动态化的hash超时,应该是申请内存的时候占用了太多的CPU的资源吧。这题sort+二分也可以做,但是map就不能搞了,可见STL的效率啊! 1 //STATUS:C++_AC_4844MS_132304KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #in 阅读全文
posted @ 2012-12-22 16:00 zhsl 阅读(315) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=3295 水题本质。数据量小,直接枚举判断即可。但要注意在搜索的时候,如果进行逻辑运算&&和||时, 存在短路特性的!比如,dfs(cur+1)||dfs(cur+2),如果dfs(cur+1)==ture,那么dfs(cur+2)就不会访问了,所以导致cur的下标访问出错,那么我们在写这种表达式的时候,把dfs分别赋值然后再去进行逻辑判断是一种好习惯,可以减少不必要的错误!我开始这里没有注意好,wa了!然后还提一下,C++是从逻辑判断符的右边开始判断的,而G++是从左边开始的,也就是这题有些人C++和G++不能同时 阅读全文
posted @ 2012-12-16 15:40 zhsl 阅读(252) 评论(0) 推荐(0)
摘要:题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3182 最大点权独立集。算法是建立网络流模型,加源汇点s和t,源点s向x集合中的每个点建立边,容量为点的权值,y集合的每个点向汇t建立边,容量为点的权值,然后x集合和y集合相关联的点建立边,容量为INF。最后求最小割就可以了,所有点的权值之和减去最小割就是最大权值,独立点集就是全集减去最小割的点集。为什么是这样的呢?其实每条增广路代表的就是一条相关联的边,找到一条增广路我们就删除一个点,如果找不到增广路了,那么剩下的点就是独立的了。由于是最小割,那么删除的点集... 阅读全文
posted @ 2012-12-15 17:15 zhsl 阅读(467) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=2135 很容易看出来时最小费用流,但这里要注意是无向边,所以要建立两条边。为了满足退流时,花费还是最小,反向边的花费要为相反数。 1 //STATUS:G++_AC_32MS_980KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<alg 阅读全文
posted @ 2012-12-15 01:27 zhsl 阅读(221) 评论(0) 推荐(0)
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3469 题目大意:警察抓小偷。有n个房间,编号1-n,小偷躲在其中的一个房间里面,警察每天早上会检查一个房间,如果小偷不在那个房间里面,那么小偷晚上会转向相邻的房间,问警察在最坏情况下需要多少天抓到小偷。 这个题目是分奇偶情况讨论。先假设小偷在第偶数个房间,那么警察从第2个房间依次向右找,知道第n-1个房间(n-1找两次),那么最多只要n-2天就可以了。如果没有找到,那么就可以肯定小偷最开始在第奇数个房间,若房间的个数n为偶数,那么小偷此时肯定在第奇数个房间,那么警察从第n-1个房间向左找到... 阅读全文
posted @ 2012-12-12 17:36 zhsl 阅读(439) 评论(0) 推荐(0)
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3998 题目大意是:给你一个数列,要你求最长的上升子序列,并且求最多有几个,且每个数只能在每个子序列中出现一次。对于第一问题很容易用DP解决,那么第二个问题,如果每个数可以出现多次的话,DP也很容易解决,但这里必须只能出现一次,否则的话就得判重,复杂度O(n3)。把问题简化一下,就是求长度为s的点不想交的路径有多少条,即每个点的容量为1(拆点),dp值相差为1的建立边,增加源汇点s、t,s向dp值为1的建立边,dp值最大的向t建立边,然后求最大流。 在网上看到这题贪心也可以搞,具体做法就是从... 阅读全文
posted @ 2012-12-11 09:42 zhsl 阅读(509) 评论(0) 推荐(0)
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3996 很无语加蛋碎的题目!题意描述不清,然后还有超int(这里wa,果断被坑)= =!方法很简单,很容易看出是最大闭合权。 1 //STATUS:G++_AC_109MS_2068KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 阅读全文
posted @ 2012-12-10 01:48 zhsl 阅读(407) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=3189 无语了,再次碰到Farmer John,又是二分+匹配的题目= =!注意题目要求求的是range最小,就是最大的rank-最小的rank! 1 //STATUS:G++_AC_94MS_1500KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #incl 阅读全文
posted @ 2012-12-06 17:02 zhsl 阅读(316) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=2391 这个题目很容易想到二分求解,我开始没有拆点,wa了很多次!后来发现,如果不拆点,二分枚举答案是没有意义的。因为在网络中,已建立的边可以相互联通,那么它们的距离相加可能会超过二分的限制,导致没有意义。那么我们可以把每个区域拆成两个点,一个在X集合,一个在Y集合,增加一个源点s和汇点t。从s向每个X集合得点建立边,容量为这个区域本原有的奶牛数,从每个Y集合的点建立边,容量为这个区域奶牛数的限制。然后,如果X集合点和Y集合点之间的最短距离小于二分限制的话那就建立边,容量为X集合点的原有的奶牛数。那么最大流就是可容纳的奶牛数... 阅读全文
posted @ 2012-12-05 18:54 zhsl 阅读(454) 评论(0) 推荐(0)
摘要:在Acm竞赛中,网络流中求最大流的主流算法有Dinic和Isap,那么这两种算法究竟选哪种好,有些人说Dinic稳定,有些人说Isap效率高,还有人说卡Dinic的题目都是不人道的。为此我分别测试了一下他们的效率。 测试的题目是POJ3469,题目的测试数据足以分辨这两个算法的效率了,所提交的语言为G++。 下面是Dinic的,没有加当前弧优化,用时5469ms。Dinic-没有当前弧优化 1 //STATUS:G++_AC_5469MS_8456KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<stri 阅读全文
posted @ 2012-12-03 18:04 zhsl 阅读(2949) 评论(0) 推荐(1)
摘要:题目链接:http://poj.org/problem?id=3469 题目的意思是这样的:有n个任务要处理,现在有一个双核心的CPU,每个任务可以在其中一个核心被完成且需要一定代价,其代价分别为Ai和Bi,如果某些任务在不同的核心上处理,可能需会要需要进行数据交换,即第a个任务和第b个任务为w(a,b,w)。现在要你分配这n个任务,使得所需的代价最小。 开始看到这个题目的时候以为是最小费用流,于是建图建了半天,也没建出来,后来看了下Discuss,才发现是最小割!关键还是在建图上:把每个任务看做点,加源点s和汇点t,从s向每个任务点建立单向边,容量为Ai。从每个任务点向t建里单向边,... 阅读全文
posted @ 2012-12-03 17:17 zhsl 阅读(435) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=2112 和POJ2455很像,也是求最大值最小,当时就想到了二分。具体做法就是:先求出每头牛到到牛奶机器的最短路,用spfa或dijkstra(也可以用floyd直接搞)从每个牛奶机器求一次最短路即可,那么这里就可以很容易的看出来可以直接用二分图最大匹配来依次二分求解最佳值,当然也可以用网络流来求最大流,加一个超级源点和超级汇点,源点到每头牛的容量为1,每头牛到每个牛奶机器的容量为1,每个牛奶机器到汇点的容量为m,那么就可以二分来做了。这个题目用二分图做法显然更简单,更方便,但我还是用网络流模型来做了,详细见代码。 1 /... 阅读全文
posted @ 2012-12-01 22:12 zhsl 阅读(287) 评论(0) 推荐(0)