上一页 1 ··· 11 12 13 14 15 16 17 18 19 ··· 21 下一页
摘要: 题目链接//2013-05-17-21.08#include #include #include using namespace std;const int maxn = 100004;int dp[maxn][12];int main(){ int n, maxt, t, x; int tmax; while(scanf("%d", &n) && n) { memset(dp, 0, sizeof(dp)); maxt = 0; for (int i = 0; i = 0; t--) { f... 阅读全文
posted @ 2013-05-17 21:06 xindoo 阅读(212) 评论(0) 推荐(0) 编辑
摘要: 题目链接 题目很长,看加猜加谷歌翻译才看懂了题目。每级台阶的宽都是1,但高不同,并且告诉你了,然后给你m个箱子,长和宽都告诉你,把箱子靠左放,求箱子的底部有多高。 因为都是放在最左边的,所以只要和最左边的高度比较,这样就不用更新线段树了。代码://cf 272 C//2013-05-14-20.26#include using namespace std;const int maxn = 100005;struct node{ int l, r, mid; __int64 m;}tree[maxn b) return a; return b;}void bui... 阅读全文
posted @ 2013-05-14 20:28 xindoo 阅读(187) 评论(0) 推荐(0) 编辑
摘要: 题目链接题意: 给你一个字符串,在字符串尾部加上一些字符,使这个字符串变成一个回文串(正反读都一样的字符串),求该回文串的最小长度。思路: 在light oj里这个题目是属于KMP分类的,但乍看好像不是kmp,因为只有一个字符串。要想的到一个回文串,把该字符串翻转接到原串后面必然是一个回文串,但并不一定是最短的。我们必须考虑怎么把两个串尽量融合在一起,这就要看翻转串的前段与原串的后段有多少是匹配的了,这里就用到了KMP算法。代码://2013-05-13-20.01#include #include const int maxn = 1000005;char a[maxn];char b[.. 阅读全文
posted @ 2013-05-13 20:10 xindoo 阅读(120) 评论(0) 推荐(0) 编辑
摘要: 题目链接题意: 输入两个字符串,计算二串在一串中出现的次数。 裸裸的KMP,参考刘汝佳《算法竞赛入门经典训练指南》 P212 或数据结构。代码如下://light oj 1255 - Substring Frequency (KMP)//2013-05-13-19.12#include #include const int maxn = 1000006;char a[maxn];char b[maxn];int f[maxn];void getfail(){ int l = strlen(b); f[0] = 0; f[1] = 0; for (int i = ... 阅读全文
posted @ 2013-05-13 19:10 xindoo 阅读(132) 评论(0) 推荐(0) 编辑
摘要: 题目链接 如果你是刚刚开始做状态压缩dp,我建议你先看看 poj 3254 Corn Fields 这是一道比这一题更简单,更容易入门的题目。 还有在代码中我用了一个很巧妙的方法求一个数二进制数中1的个数 具体请看我博客中 x& (x - 1)==0这篇文章 链接。 还有一点,不同于poj 3254的地方,我们不能直接枚举所有的状态。我在getresult()中用到了四重循环,直接枚举的时间复杂度是2^40,并且dp那个数组也是开不下到,不过对于这道题还是有方法的。枚举一行所有的状态,行合法(没有两个1相隔少于两个)的状态总共有61中,我们只需要枚举所有合法状态即可,循环次数最多是61 阅读全文
posted @ 2013-05-08 20:16 xindoo 阅读(135) 评论(0) 推荐(0) 编辑
摘要: 题目链接题意:Farmer John 放牧cow,有些草地上的草是不能吃的,用0表示,然后规定两头牛不能相邻放牧。问你有多少种放牧方法。 状态压缩dp其实就是用二进制来表示所有的状态,比如这题, 我们在某一行可以这样取0 1 0 1 1 0 1,用1代表取了,0代表没取,因为这点,它的数据量也限制在20以内,所有看到这样数据量的题目可以先考虑一下状态压缩dp。对于有多行的数据,所有状态的总数必然很庞大,而且不用特殊的方法想要存储这些状态是不太现实的。既然每个点只有这两种情况,我们可以用二进制的一位来表示,0 1 0 1 1 0 1就可以表示为二进制0101101也就是十进制的45,如果我们.. 阅读全文
posted @ 2013-05-07 20:21 xindoo 阅读(169) 评论(0) 推荐(0) 编辑
摘要: 题目链接题意:在一个n*n的棋盘上放m个车,使得各个车之间不相互攻击。有多少种放法?组合数学解法 现在n行中选出m行,C(n,m),再在n列中选出m列随便放A(n,m),答案为C(n,m)*A(n,m)。#include #include typedef __int64 LL;LL A(int n, int m){ LL ans = 1; for (int i = n-m+1; i <= n; i++) ans *= i; return ans;}LL C(int n, int m){ LL ans = 1; for (int i = 1; i <=... 阅读全文
posted @ 2013-05-06 20:28 xindoo 阅读(133) 评论(0) 推荐(0) 编辑
摘要: 题目链接题意: 题目的大概意思是把数组分成不交两段,分别求出两段的最大子段和s1和s2,然后求出最大的s1+s2。不知道最大子段和的点这 here思路: 看完最大连续子段和 的 dp算法这个很容易理解,我用dplift[i]保存第1到第i个之间的最大子段和,dpright[i]保存第i到第n个之间的最大子段和,最终结果就是dplift[i]+dpright[i+1]中最大的一个。代码//poj 2479 Maximum sum//2013-05-01-17.26#include #include #include using namespace std;const int maxn =... 阅读全文
posted @ 2013-05-01 17:47 xindoo 阅读(154) 评论(0) 推荐(0) 编辑
摘要: 问题描述: 有n个数(以下都视为整数,浮点的也一样),每个数有正有负,现在要在n个数中选取相邻的一段,使其和最大,输出最大的和。问题分析: 对于这样的问题,我们可以直接用暴力,一个双重循环,虽说可以,但也没有更高明的方法? 我们再分析这个问题,如果我们知道了某个数前面一段数的和,我们就该考虑把这个数加入到前一段,还是重新开始一段。这个地方很重要,如果前一段的和小于0,我们重新建一段,反之加到前一段。这样我们就可以把n个数分成几段了,且每一段都求出了他们的和,然后再循环一次求出最大的一个和,我们就得到想要的结果了,也可以在分段的时候直接求结果。代码int MaxSub (int a[]){ .. 阅读全文
posted @ 2013-05-01 17:32 xindoo 阅读(213) 评论(0) 推荐(0) 编辑
摘要: 题目链接大致题意:有n跟棍, 求它们能组成最短且长度相同的棍的长度解题思路:DFS+剪枝POJ2362的强化版,重点在于剪枝 建议你先看看这道题 here令initlen为所求的最短原始棒长,maxlen为给定的棒子堆中最长的棒子,sumlen为这堆棒子的长度之和,那么initlen必定在范围[maxlen,sumlen]中,cnt为可能组成的数目,也就是sunlen/maxlen。根据棒子的灵活度(棒子越长,灵活度越低) DFS前先对所有棒子降序排序剪枝:1、 由于所有原始棒子等长,那么必有sumlen%Initlen==0,这个我在main函数中做了。2、 若能在[maxlen,suml. 阅读全文
posted @ 2013-04-30 09:11 xindoo 阅读(233) 评论(0) 推荐(0) 编辑
上一页 1 ··· 11 12 13 14 15 16 17 18 19 ··· 21 下一页