紫书-第8章-高效算法设计
文章平均质量分 69
冷月残星
这个作者很懒,什么都没留下…
展开
-
分治法,最小权完美匹配(巨人和鬼,Ants,uva 1411)
分治法解法:感觉能用分治法解的问题都有自相似性吧。就是说把大的情况按某种方式切成几个小的情况,这些小的情况和大的情况是相似的。如果满足这个条件,那么最简单的情况的解答方案是显然的。我们只需要考虑好如何合并多个小情况即可。跟快速排序的思想很像啊。看紫书P227吧,讲的详细。最小权完美匹配解法:黑点和白点个数相同,每个黑点要找一个白点,应该要想到二分图完美匹原创 2016-08-20 16:42:58 · 3692 阅读 · 2 评论 -
滑动窗口(唯一的雪花,uva 11572)
紫书上说的很好了。#includeusing namespace std;int main(){ int t; scanf("%d",&t); while(t--) { int n; vectorvec; int temp; scanf("%d",&n); for(i原创 2016-09-05 12:41:18 · 665 阅读 · 0 评论 -
双重有序,单调栈(贩卖土地,uva 12265)
#include#define maxn 1010using namespace std;typedef pair pii;int n,m;char MAP[maxn][maxn];int MAX[maxn][maxn];mapans;vectors;void cl(){ s.clear();}void ps(pii x){ if(s.size())原创 2016-09-15 23:46:56 · 659 阅读 · 0 评论 -
神奇的题(存石油的洞穴,uva 1442)
太特么机智了。#include#define maxn 1000010using namespace std;int n;int p[maxn];int s[maxn];int h[maxn];int main(){ int Z; scanf("%d",&Z); while(Z--) { scanf("%d",&n原创 2016-09-15 20:33:37 · 607 阅读 · 0 评论 -
模拟,滚动数组,递归(不公平竞赛,uva 1609)
用递归的思想求解。n是2的整数幂,应该要想到递归的思想的。但不是用递归函数求解的。而是直接模拟。想办法组织一轮比赛,使得比赛过后剩下的n/2个人依然满足条件。当n=2时结果是显然的。紫书上讲的很详细。一开始用滚动集合做,= =超时了。。。集合真的好慢啊。然后改用滚动vector了。当n等于2时若满足题目条件,答案是显然的。一开始时就满足题目条件,因此我们每轮比赛原创 2016-09-15 00:12:12 · 626 阅读 · 0 评论 -
分治法,中途相遇法(Non-boring sequences,uva 1608)
分治法很容易想到。中途相遇法真是个神奇的东西。意思大概就是,你可以从两边出发去寻找答案,然而无论你从那一边出发,随着寻找的次数逐渐增多,枚举量飞速增长,因此你不如从两边一起找,这样两边的枚举量都能显著控制在较低水平,从而提高程序效率。感觉在uva超时了就很有可能是数组越界了。。。代码#include#define maxn 200010#define INF原创 2016-09-13 21:43:55 · 743 阅读 · 0 评论 -
滑动窗口,预处理(Shuffle,uva 12174)
想要快速查询,可以考虑先预处理。经典滑动窗口。自己的debug能力太弱了,基本靠对拍,这样吃枣药丸。多总结下debug技巧,这能力真的很重要的。#include#define maxn 100010using namespace std;int a[maxn];int tong[maxn<<1];int cnt[maxn];int CNT;int s,n;原创 2016-09-13 20:34:58 · 1613 阅读 · 0 评论 -
贪心(Fabled Rooks,uva 11134)
一些参考 http://acm.lilingfei.com/uva-11134-fabled-rooks-%E4%BE%8B%E9%A2%988-4_67 http://blog.csdn.net/shuangde800/article/details/8653730行和列无关的意思是,本题可以拆成两个完全独立的子问题,分别是行和列的问题转载 2016-09-02 00:20:47 · 472 阅读 · 1 评论 -
中途相遇法,哈希技术(和为0的4个值,uva 1152)
题目具有对称性,则可以同时从两边出发来找答案,因为时间复杂度由最大的决定,因此让两边时间复杂度尽量一样可以降低总体的时间复杂度,此题中n^2logn+n^2logn试了下map,9秒超时,用哈希3.540秒。还是快很多的。因为map随着数据量的增多,logn的时间复杂度开始拖慢速度。而哈希大部分时候都是O(1),极端情况下是O(n)。极端情况一般都不用考虑,除非题目是特殊设原创 2016-08-23 15:55:57 · 788 阅读 · 0 评论 -
二分(Gates,uva 1607)
虽然AC了。但是我认为这道题是有问题的。紫书上说:先把x设为0,再把x设为1,如果二者的输出相同,整个电路肯定是常数,任意输出一种方案即可。可是事实上并不是这样。比如这组数据16 5-2 -3 -4 -5 -1 1 -6 2 3 4满足紫书上的条件,然而整个电路却并不是常数。加入如下的代码来debug。for(int i=0;i<=n;i++)原创 2016-09-13 12:10:46 · 612 阅读 · 2 评论 -
水题(联合国大楼,uva 1605)
#includeusing namespace std;int main(){ int n; bool fir=true; while(scanf("%d",&n)!=EOF) { if(!fir) puts(""); fir=false; printf("%d %d %d\n",2,n,n);原创 2016-08-23 06:08:26 · 464 阅读 · 0 评论 -
水题(翻煎饼,uva 120)
学习了一些输入输出技巧,还有字符串反转函数。输出时要先把输入输出一遍。。。#includeusing namespace std;char s1[1000];string s2;int main(){ while(cin.getline(s1,1000)) { s2=s1; cout<<s2<<endl;原创 2016-08-23 05:54:26 · 801 阅读 · 0 评论 -
哈夫曼编码,元素为指针的优先队列
http://blog.csdn.net/huangxy10/article/details/80299623.下面是将指针存在优先队列中的方式struct Node{ short f; short d; short fishs; short times; short i;}; struct PCmp{ b转载 2016-08-23 04:25:33 · 1036 阅读 · 0 评论 -
优化(Just Finish it up,uva 11093)
#include#define maxn 100010using namespace std;typedef long long ll;ll jia[maxn];ll jian[maxn];ll N;inline ll next(ll now){ if(now==N) return 1; else return now+1;}inline ll run(l原创 2016-09-12 19:22:28 · 387 阅读 · 0 评论 -
分治法(Erratic Expansion,uva 12627)
#includeusing namespace std;typedef long long ll;ll san[35];ll er[35];void init(){ san[0]=er[0]=1; for(ll i=1;i<=30;i++) { san[i]=san[i-1]*3; er[i]=er[i-1]<<1;原创 2016-09-12 18:27:44 · 258 阅读 · 0 评论 -
哈夫曼编码(Add All,uva 10954)
#includeusing namespace std;typedef long long ll;struct cmp{ bool operator () (ll a,ll b) { return a>b; }};int main(){ ll N; while(scanf("%lld",&N)==1&&N) {原创 2016-09-12 17:32:55 · 287 阅读 · 0 评论 -
二分,贪心(Copying Books,uva 714)
最大值尽量小,二分加判断可不可行。这个方法十分重要。判断方法用贪心。一些优化:二分的左边界为最大值,二分的右边界为和。判断时发现不可行立刻返回。字典序最小,从右往左贪心即可,因为若右边的多拿了左边的东西,那么左边就有机会拿更左边的东西。分组不能为空集,所以贪心到后面组不够了,那就直接一人一组。搞了很久,因为一些算法有问题,所以有死循环没发现。代码原创 2016-09-12 17:21:16 · 314 阅读 · 0 评论 -
斜率优化,数形结合(Average,uva 1451)
[i,j]这个子串的值是点i-1,与点j之间的斜率。求所有子串的最大值就是求i-1到j的斜率的最大值。每个点的横坐标为在子串中的位置(第几个),纵坐标为sum[i-1]。问题转化为求n+1个点中(加入坐标原点)找两个点,横坐标至少相差L且斜率最大。这个思路想清楚后剩下的就全是数学问题了,详见紫书P243。代码写的不好。修修补补,cmp不是在比较斜率,而是在比原创 2016-09-12 13:07:05 · 369 阅读 · 0 评论 -
高效(防线,uva 1471)
参考 http://blog.csdn.net/L123012013048/article/details/45054857一开始用set弄,erase弄超时了。后半部分的方法十分不错。一方面思路用二分搜索代替了暴力枚举。另一方面,这种技巧有时能代替低效的set,大大提高效率,今后解题都可以参考。前面的滑窗也有许多小细节需要处理。#includeusi转载 2016-09-07 19:48:15 · 550 阅读 · 0 评论