上一页 1 2 3 4 5 6 7 8 9 ··· 23 下一页
摘要: 模型:给一个n个点的无向带权图,求从指定起点出发,经过指定的k个点(顺序不定)最后回到起点的最小代价。数据范围:n<=10^4, m<=10^5, k<15分析:先求最短路,求出从指定的k+1(含起点)个点到其他点的最小代价,然后建立k+1个点之间的最小代价邻接矩阵。最后用状态压缩DP求结果(状态压缩DP参考上一篇)。View Code #include <stdio.h>#include <string.h>#include <queue>using namespace std;#define MIN(a,b) ((a)<(b)?( 阅读全文
posted @ 2012-08-05 09:49 BeatLJ 阅读(311) 评论(0) 推荐(0) 编辑
摘要: 模型:求n个城市的最短hamilton回路,n<=15。分析:看到n<=15这样的条件容易想到状态压缩DP。hamilton回路其实就是n个城市的一个圆排列,任选一个起点最后的结果都一样,我们不妨设结点0为起点,状态设计也就不难了。状态设计:d[s][last],表示从结点0出发,已经走过的结点构成状态s,最后走的结点为last;状态转移:d[s][last]=MIN(d[ns][k]+g[k][last]),ns为s中去掉last那一位,k为ns中是1的位(不能是起点0);边界:当s中只有2位是1的时候,说明从0结点出发,到达last,所以直接返回g[0][last]。结果:an 阅读全文
posted @ 2012-08-05 09:37 BeatLJ 阅读(273) 评论(0) 推荐(0) 编辑
摘要: 题意:给一个正整数序列,记为a1,a2,……an,现需找i,j,使得i<j,并且ai与aj之间的数均比ai大,均比aj小,求符合上述条件的i与j,使得j-i的最大。分析:易知序列中的最小值比其他所有数都小,最大值比其他所有数都大,所以可以现找到最小的数与最大的数的位置,记为i,j,若i<j,则区间[i,j]内符合上述条件的最值就是j-i,然后递归求解左右区间[1,i-1],[j+1,n],若i>j,则将区间分为三段递归求解,[1,j],[j+1,i-1],[i,n]。递归边界为区间左端点>=区间右端点时返回-1。每次求区间的最大与最小值的位置可以用线段树解决。View 阅读全文
posted @ 2012-08-03 23:59 BeatLJ 阅读(268) 评论(0) 推荐(0) 编辑
摘要: 题意:给一棵含n个结点的树,现要查询从a到b的路径中是否包含c,共q次查询。1=<n,q<=100000分析:由于在树中从一个结点走到另一个结点的路径是唯一的,其实说的这条路径就是最短路径,然后问题转化为判断一个点是否为在一条最短路径上,此时就不难想到这个这个判断条件d(a,c)+d(c,b)=d(a,b),问题就转化为查询树中2个结点之间的距离,这个可以用LCA来做(参考上一篇),考虑到n和q都比较大,所以用离线LCA.View Code #include <stdio.h>#include <string.h>#define N 100010#defin 阅读全文
posted @ 2012-08-03 23:27 BeatLJ 阅读(231) 评论(0) 推荐(0) 编辑
摘要: 题意:给一棵带权重的树,共有k个查询,每次查询树中2个结点的距离。结点数n最大为40000,k最大10000分析:首先我们将无根树转为有根树,可以在O(n)时间内得到每个结点到根结点的距离。由于在树中从一个结点走到另一个结点的路径是唯一的,所以a到b的路径一定经过lca(a,b),设lca(a,b)=c。此时不难发现d(a,b)=d(a,root)+d(b,root)-2*d(c,root)。先在问题就是如何快速求LCA,由于结点数目比较大,查询比较多,所以用在线算法会超时。这里用的是tarjan离线算法,时间复杂度为O(n+k)。View Code #include <stdio.h& 阅读全文
posted @ 2012-08-03 23:15 BeatLJ 阅读(939) 评论(0) 推荐(0) 编辑
摘要: 模型:给定一个整数矩阵,查询某个子矩阵中的最大数与最小数之差。N最大为250,查询数K最大为100000我的做法:用线段树求出要查询的子矩阵每一行的最大与最小,然后在列方向上统计子矩阵的最大与最小。有点暴力,跑了800+ms。View Code #include <stdio.h>#include <string.h>#define N 255#define MAX(a,b) ((a)>(b)?(a):(b))#define MIN(a,b) ((a)<(b)?(a):(b))int n,b,k,D;int max[N][4*N];int min[N][4* 阅读全文
posted @ 2012-08-03 17:40 BeatLJ 阅读(253) 评论(0) 推荐(0) 编辑
摘要: 题目大意:给你一个含n个整数的不下降序列,现需查询某个区间内出现次数最多的数,对于每次查询输出出现最多的次数即可。分析:由于序列是有序的,所以一个数如果在序列中出现多次,那么一定是连续出现的,这样的话就可以把问题转化为区间染色问题,查询的是某个区间中最长的同色区间的长度。区间保存的关键信息有,区间内的某数出现的最大次数,区间最左边的数及其在该区间内出现的次数,区间最右边的数及其在该区间内出现的次数。保存左右两边的信息为为了更新父结点,因为父结点的最大answer可能由左儿子和右儿子合并得到。这题我一开始用堆实现的线段树,发现了很多问题,用堆实现的线段树中有很多没有用到的空间,处理不好会造成结果 阅读全文
posted @ 2012-08-03 17:34 BeatLJ 阅读(224) 评论(0) 推荐(0) 编辑
摘要: 定义windy数:相邻数字的差至少是2的数,例如10不是windy数,而13是windy数。求给定区间中有多少windy数。区间端点范围为 [1, 2000000000]dfs写法#include <stdio.h>#include <string.h>#define N 10int dp[N][N],digit[N];int dfs(int pos,int last,int z,int f){ if(pos==-1) return 1; if(z&&!f&&dp[pos][last]!=-1) return dp[pos][last]; 阅读全文
posted @ 2012-08-02 17:32 BeatLJ 阅读(1022) 评论(0) 推荐(0) 编辑
摘要: 题意:求n到m中有多少个数不含“4”和“62”View Code #include <stdio.h>#include <string.h>#define LEN 10char a[LEN],b[LEN];int n,m;int dp[LEN][3][2];int nextstate(int cur,int in){ if(cur==2 || cur==1&&in==2 || in==4) return 2; return in==6;}int nextflag(int cur,int in,int max){ if(cur==1 && 阅读全文
posted @ 2012-08-01 23:53 BeatLJ 阅读(468) 评论(0) 推荐(0) 编辑
摘要: 题目大意:求1到n中有多少个数含“49”第一次接触按位DP,参考了别人的题解。第一个代码运行速度快些(31ms),但状态的转移的分析比较麻烦,第二个代码要慢些(125ms),但code比较方便。View Code #include <stdio.h>#include <string.h>#define LEN 22typedef __int64 LL;char s[LEN];LL dp[LEN][3][2];int next(int cur,int in){ if(cur==2 || cur==1&&in==9) return 2; return in= 阅读全文
posted @ 2012-08-01 23:48 BeatLJ 阅读(212) 评论(0) 推荐(0) 编辑
上一页 1 2 3 4 5 6 7 8 9 ··· 23 下一页