上一页 1 ··· 60 61 62 63 64 65 66 67 68 ··· 85 下一页
  2011年11月15日
摘要: UVA_10534 这个题目需要用到nlogn求最长上升子序列的算法。 算法的思想大概是这个样子,维护一个栈,在扫描过程中,如果当前元素比栈顶元素大,那么就将其加入到栈顶,否则在栈内用二分查找找到恰好不小于当前元素的某一值,并将其替换掉。当前元素为终点的最长上升子序列的长度就是该元素入栈时的位置。 实际上就是运用了贪心的思想,每次进行替换操作后增强了后续最长上升子序列的“长度增长的潜力”,后续得到的解一定不会比不替换更优。 简单证明一下其正确性。我们用a[i]替换掉了S[mid],对后续某一元素a[j]来讲,可能会认为此时a[j]前的元素标号并不是严格升序了,这会不会有问题呢?实际是不... 阅读全文
posted @ 2011-11-15 01:17 Staginner 阅读(439) 评论(0) 推荐(0) 编辑
  2011年11月14日
摘要: UVA_12295 之前最早使用SPFA+qsort实现的优先队列写的这个题目,今天又重新用不同的方式写了一遍这个题目,即SPFA+手写堆实现的优先队列,SPFA+记忆化搜索,在Dij的过程中顺便记录路径条数等这样三种方式。 写完之后,和预想的一样SPFA+手写堆实现的优先队列是最慢的,但对于剩下两个写法感觉得到的结论和网上看到的一篇文章写的不太一样,他说对于网格类数据Dij要明显比SPFA快一些,但就我的测试结果来看,实际上SPFA最后再加一个记忆化搜索所需的时间都要比Dij更快一些(Dij只是顺便记录了路径条数)。当然,也有可能是我自己写的堆优化的Dij效率比较低,而且我在本地用的是1.. 阅读全文
posted @ 2011-11-14 16:18 Staginner 阅读(283) 评论(0) 推荐(0) 编辑
摘要: UVA_825 一个比较容易的计数问题,如果(i,j)这个点可以通过的话f[i][j]=f[i-1][j]+f[i][j-1],否则f[i][j]=0。#include<stdio.h>#include<string.h>#include<ctype.h>#define MAXD 1010char b[10010];int N, M, G[MAXD][MAXD], f[MAXD][MAXD];void solve(){ int i, j, k; gets(b); sscanf(b, "%d%d", &N, &M); mem 阅读全文
posted @ 2011-11-14 00:17 Staginner 阅读(415) 评论(0) 推荐(0) 编辑
  2011年11月13日
摘要: HDU_3474 我们可以把C看成1,J看成-1,那么原问题就转化成了对于任意一种情况,如果序列从左往右加或者从右往左加,存在其一使得在加的过程中中间结果始终不为负数,那么这种断开的情况就是符合要求的。 我们不妨把环处理成两个相同的序列,并计算出其前缀和A[i],那么对于任意一种左端点为i,右端点为j的情况,如果min{A[k]}-A[i-1]>=0或者A[j]-max{A[k]}>=0,那么这种情况就是符合要求的,其中i-1<=k<=j,于是两个单调队列分别维护A[k]的最小值及最大值即可。#include<stdio.h>#include<stri 阅读全文
posted @ 2011-11-13 22:24 Staginner 阅读(224) 评论(0) 推荐(0) 编辑
  2011年11月10日
摘要: HDU_3415 由于原序列是一个环,为了方便处理可以在序列尾补K-1个元素,从而变成了链。设前i项和为A[i],f[i]为右边界在第i项上时的最大和,则f[i]=max{A[i]-A[j]}(i-K<=j<i),于是我们可以用一个单调队列来维护至今遇到的最小的A[j]即可,且i-K<=j<i。 由于要求序列非空(或者说要求j<i),所以插入操作要放到最后去做,同时一开始要向队列里插入一个标号为0且值为0的元素。#include<stdio.h>#include<string.h>#define MAXD 200010#define INF 阅读全文
posted @ 2011-11-10 23:20 Staginner 阅读(491) 评论(0) 推荐(0) 编辑
摘要: POJ_2823 这个是在接触了单调队列优化后的第一个题目,其实个人感觉单调队列所作的优化就是维护了一个始终保存当前最优解的队列。 解的合法性是通过队列内各元素的标号的单调性保证的,每次要通过队首删除元素的操作来保证队列内的解是在当前区间内的。 队首元素的最优性则是由队列内元素值的单调性保证的,每次要通过将队尾不比当前待插入的元素更优的元素删除来保证了队首元素的最优性。#include<stdio.h>#include<string.h>#define MAXD 1000010int N, K, f[MAXD], d[MAXD], qf[MAXD], nf[MAXD], 阅读全文
posted @ 2011-11-10 16:28 Staginner 阅读(365) 评论(0) 推荐(1) 编辑
  2011年11月9日
摘要: SPOJ_9939 这个题目可以用2-SAT做。 首先既然是2-SAT的问题的话,我们就要去找核心变量,然而B的每局的选择却是3个,石头(1)、剪子(2)、布(3),难道3-SAT?开玩笑,目前至少我没见过3-SAT的题目。仔细想一下,其实选择也就两个,因为A的选择是定的,而我们必须让A赢,因此B的选择实际上只有两个。 找到核心变量之后就是构图了,由于构图要稍复杂一些,就不直接用字母代替了,还是用一个实例来说明一下吧。 我们不妨一共3局,A出的分别是1、2、3,那么我们可以得到B的选择如下。 B1 1 2 1 B2 2 3 3 !B 3 1 2 其中B1、B2为B的两个选择,!... 阅读全文
posted @ 2011-11-09 20:14 Staginner 阅读(302) 评论(0) 推荐(0) 编辑
摘要: UVA_620 话说真的不知道为什么这道题目会放在动规的分类里,只要递归判断就可以了。如果存在多个状态的话,要输出细胞成长最后一个的状态。#include<stdio.h>#include<string.h>#define MAXD 100010int N, max;char b[MAXD];void dfs(int s, int t, int flag){ if(s == t) { if(b[s] == 'A') { if(flag) max = 1, flag = 0; } ... 阅读全文
posted @ 2011-11-09 01:36 Staginner 阅读(343) 评论(2) 推荐(0) 编辑
摘要: UVA_10404 我们可以用一个数组f[i]表示当还有i个石子该Stan取的时候,Stan是否能够获胜。这时,对m种取法都要考虑一遍,如果存在一种取法r[j]使得i>=r[j]并且f[i-r[j]]=0时,就说明如果Stan按这种取法走就会必胜,因此f[i]就标记为1即可。 最后只要看f[N]是否为1即可。#include<stdio.h>#include<string.h>#define MAXD 1000010#define MAXM 15int N, M, f[MAXD], r[MAXM];void init(){ int i; scanf("% 阅读全文
posted @ 2011-11-09 01:11 Staginner 阅读(371) 评论(4) 推荐(0) 编辑
  2011年11月6日
摘要: UVA_437 首先将一个长方体变成3个来存储,然后按底面积的大小升序排列,最后求一个最长上升子序列即可。#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXD 110int N, f[MAXD], a[5][MAXD], r[MAXD];int cmp(const void *_p, const void *_q){ int *p = (int *)_p; int *q = (int *)_q; return a[0][*p] * a[1][*p] - a[0][*q] * a[1 阅读全文
posted @ 2011-11-06 22:03 Staginner 阅读(449) 评论(0) 推荐(0) 编辑
上一页 1 ··· 60 61 62 63 64 65 66 67 68 ··· 85 下一页