上一页 1 ··· 6 7 8 9 10 11 12 13 14 下一页
摘要: 这题好难,我不写题解了,直接转发吧:KMP算法大家应该烂熟于心才好,这样碰到这样的题才能灵活运用。有时做题真的需要一点灵感。首先,这个题如果想要求出从每个位置开始的字串的匹配长度,那么O(n^2)以内的算法应该是很难的。但是,这个题要求的并不是“每个位置的长度”,而是“具有这样长度的位置数”。因而,灵活使用KMP算法自我匹配的性质,就能够解决这个问题。考虑下面的例子:A串:abbabbabababbababbaB串:abbabababba应用KMP算法,很容易得到B串的自我匹配是元素 a b b a b a b a b b a位置 1 2 3 4 5 6 7 8 9 10 11长度 0 0 . 阅读全文
posted @ 2011-07-14 11:51 zqynux 阅读(458) 评论(0) 推荐(0) 编辑
摘要: 这个题目有点价值吧,设f[i]为i的不同组合有多少种,那么i就可以表示成(i - 1) + 1,也就是i - 1有多少种排列i就有多少种,但是比如i=6的时候,可以表示成2+2+2, 4+2,这里没有出现1,怎么办呢?可以看到i为偶数的时候一定可以把i表示成2*(i / 2)。 然么就可以得到: f[i]=f[i - 1], i 为奇数时 f[i]=f[i - 1] + f[i / 2], i为偶数时,又题目说9位数,所以要求模。 代码:#include <stdio.h>#include <stdlib.h>int f[10000001];int main(int a 阅读全文
posted @ 2011-07-12 22:11 zqynux 阅读(330) 评论(0) 推荐(0) 编辑
摘要: 简单DP,设f[i][j]是取i个数,左边取j个,转移方程: f[i][j] = max(f[i - 1][j - 1] + i * num[j], f[i - 1][j] + i * num[n - (i - 1 - j)]);2011年7月16日 08:55:21添加: 昨晚删数那题,又看了下这题,就觉得这题不能用区间动态规划吗?仔细对比了一下,还真不能,这里的i无法用区间动态规划里的什么来表示,所以这里不能用区间动态规划。 代码如下:#include <stdio.h>#include <stdlib.h>int num[2001];int f[2001][200 阅读全文
posted @ 2011-07-12 20:40 zqynux 阅读(191) 评论(0) 推荐(0) 编辑
摘要: 转自:http://www.felix021.com/blog/read.php?1587 http://fayaa.com/code/view/13122/raw/ 这篇也不错,自己点开看吧: http://www.wutianqi.com/?p=1850今天回顾WOJ1398,发现了这个当时没有理解透彻的算法。看了好久好久,现在终于想明白了。试着把它写下来,让自己更明白。最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS。排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了。假设存在一个序列d[1..9] = 2 1 5 3 6 . 阅读全文
posted @ 2011-07-12 19:18 zqynux 阅读(941) 评论(0) 推荐(0) 编辑
摘要: DFS,枚举,结构上我没加什么优化,很明显有,因为上下可以对称,左右可以对称,对角线也可以对称,但是太复杂了,难得写,就没去优化。 就是对角线上的枚举可能有点让人看不懂吧,我觉得自己画个图,把每个坐标写好,然后看对角线的坐标之间的共同特点就知道该怎么枚举了,代码:#include <stdio.h>#include <stdlib.h>int num[100];int max_[100][101], min_[100][101];int sum[100][101];#define min(a, b) ((a)<(b)?(a):(b))#define max(a, 阅读全文
posted @ 2011-07-11 22:57 zqynux 阅读(438) 评论(0) 推荐(0) 编辑
摘要: 题目一直没看懂,最近终于看懂了题目,不怎么难,就是DP,和石子合并一模一样,不细说了(打工好累,想睡了。) 代码:#include <stdio.h>#include <stdlib.h>int num[100];int max_[100][101], min_[100][101];int sum[100][101];#define min(a, b) ((a)<(b)?(a):(b))#define max(a, b) ((a)>(b)?(a):(b))int rpn = 0xFFFFFFF, rpx;int main(int argc, char **a 阅读全文
posted @ 2011-07-11 22:50 zqynux 阅读(341) 评论(0) 推荐(0) 编辑
摘要: 直接DFS,没太多说的,比较简单的题目:#include <math.h>#include <stdio.h>#include <stdlib.h>int num[10];int put[10];int used[10];unsigned ans;int n, k;int ok(int a, int b){ if(abs(num[a] - num[b]) <= k){ return 1; } return 0;}void srch(int now){ int i; if(now == n){ //最后还要判断一下now - 1是否和1满足这个条件 if 阅读全文
posted @ 2011-07-10 21:36 zqynux 阅读(222) 评论(0) 推荐(0) 编辑
摘要: 挺好的一个题目,第一次做博弈类型的题目,希望TYVJ里还有更多的这类题目给我做,f[i][j]代表上一次对手取了j个,自己还有i个可取的时候能取的最大值,方程如下: f[i][j] = max(sum[i]-f[i-k][k]) (1<=k<=2*j),然后可以看到f[i][j - 1]会把1<=k<=2*(j-1)计算一次,而f[i][j]又要计算一次,重复了。所以……可以修改成: f[i][j] = max(f[i][j - 1], f[i - 2 * j][2 * j], f[i - (2 * j - 1)][2 * j - 1]); 把这段话记录一下:首先明确这 阅读全文
posted @ 2011-07-09 16:15 zqynux 阅读(249) 评论(0) 推荐(0) 编辑
摘要: 这题的模式需要记住一下,当需要从上下同时得到最优的时候,我记得还有一题NOIP的原题也是这个类型的,题目。。合唱队形也是类似的,两个DP相加。 这题还是有一点学习和参考的价值,代码:#include <stdio.h>#include <stdlib.h>int f1[27][27], f2[27][27], num[26][26];#define max(a, b) ((a)>(b)?(a):(b))int main(int argc, char **argv){ int n; int i, j; scanf("%d", &n); f 阅读全文
posted @ 2011-07-08 17:53 zqynux 阅读(250) 评论(0) 推荐(0) 编辑
摘要: 一定要经过n / 2, n / 2,就是说从上面到n / 2这一行都只能取最右边的一个,然后下面的部分DP就行了。 代码:#include <stdio.h>#include <stdlib.h>int num[25][25];int f[26][25];#define max(i, j) ((i)>(j)?(i):(j))int main(int argc, char **argv){ int i, j; int n, ans = 0; scanf("%d", &n); for(i = 0; i < n; i++){ for(j 阅读全文
posted @ 2011-07-08 15:33 zqynux 阅读(353) 评论(0) 推荐(0) 编辑
上一页 1 ··· 6 7 8 9 10 11 12 13 14 下一页