上一页 1 ··· 40 41 42 43 44 45 46 47 48 ··· 66 下一页
摘要: #include <cstdlib>#include <cstring>#include <iostream>using namespace std;int p[1005], w[1005], dp[1005][1005], N, V;void DP(){ memset(dp, 0, sizeof (dp)); for (int i = 1; i <= N; ++i) { for (int j = V; j >= 0; --j) { if (j >= w[i] && dp[i-1][j-w[i]] + p[i] > d 阅读全文
posted @ 2012-06-27 12:48 沐阳 阅读(748) 评论(0) 推荐(0) 编辑
摘要: 该题应该有很多的解法,想过用二分查找,但是排序操作的复杂度让我们伤不起。这里用Splay来实现是很方便的。首先插入一个点,即第一个点,然后再依次用二叉排序树方式插入当前点,再把该点旋转到根部(这样方便我们找前驱和后继,否则需要中序遍历整棵树来确定),再在存在前驱和后继的情况下寻找前驱和后继。接下来就很好办了。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#define L(x) tree[x].ch[0]#define R(x) tree 阅读全文
posted @ 2012-06-17 13:57 沐阳 阅读(338) 评论(0) 推荐(0) 编辑
摘要: 该题是一道简单的区间求和题,跟杭电的敌兵布阵很是想象,这里是使用Splay写的。Splay就是伸展的意思,因为该树在使用过程中会大量的执行Rotate函数,该函数就是在保持二叉树中序遍历不变的情况下,使树的结构发生变化。该题中,二叉树中存储的值并不一定要求是顺序的,满足左孩子比根节点小,右孩子比根节点大,其大小只是一个构树时的顺序关系。每次旋转能够时确保目标节点一定要在旋转节点的下方,因为任何Rotate操作旋转节点的深度都是在降低的。Splay数的作用在于能够Splay操作选出区间,首先建立两个理论上的无穷小和无穷大点,如果选择区间[a, b],那么将a-1号节点旋转到根节点,再将b+1号节 阅读全文
posted @ 2012-06-16 17:47 沐阳 阅读(572) 评论(0) 推荐(0) 编辑
摘要: 给定一个棋盘,有些点是被删除的,问在这种情况下最多能够在这个棋盘中放置多少1*2的多米诺骨牌。这题可以用二分图匹配来解决,将二维图复制出一份,将能够放置多米诺骨牌的两个相邻的点用边进行连接。如果采用邻接矩阵的话要开一个四维的数组G[x1][y1][x2][y2] 表示坐标为x1,y1 的点与x2,y2 的点之间是否放置一块多米诺骨牌。由于内存开不下,因此采用邻接表的形式来构造这些边。最后再求一个最大匹配即可。代码如下(两个代码只是邻接表的实现不同):#include <cstdlib>#include <cstring>#include <cstdio>us 阅读全文
posted @ 2012-06-13 15:41 沐阳 阅读(291) 评论(0) 推荐(0) 编辑
摘要: 这题真的要设身处地为该题想一想才能感受到这一贪心规则,题目是要求用所给定的硬币,根据面值和数目求出能每天给出不少与C元的次数。对于面值大于C的硬币,没有办法,我们只能够一次性给他们,但在这上面我们不许要再添加其他的硬币。而对于比C小的硬币,我们应该让这些分散的硬币集合到一起,使得其组合值在大于或等于C的指导思想下无限接近于C,于是对于这些硬币我就不停的塞硬币,这一次不能够超过C的值,当然我们优先会塞面值大的,因为这些硬币是不可分割的,小的硬币更具灵活性。在上一步之后,(如果没有塞到C的话)我们在考虑找一些硬币使得其值略微超过C,于是第二次我们从小的开始塞,而且一定是只塞一枚就会超过C。代码如下 阅读全文
posted @ 2012-06-12 16:48 沐阳 阅读(194) 评论(0) 推荐(0) 编辑
摘要: 解决该题的思路就是如何建立状态就保留所有的解(包括临时解)这很简单,该题只是对于某一分钟走或者是休息,而这也只改变其疲劳值,因此开一个二维数组第一维表示该走到了第几分钟,第二维表示疲劳值,保留的值为能够走得最远距离。该题还有一个地方要注意就是疲劳值为零的状态的来源有多个,可以是原来疲劳值为0,1以及能够休息到该分钟为零的任意前面一分钟。f[i][j] 表示第i分钟疲劳值为j能够走得最远距离。f[i][0] = max(f[i-1][0], f[i-k][k]) 其中 1 <= k <= i /2, 因为i-k >= k;f[i][j] (j != 0) = f[i-1][j- 阅读全文
posted @ 2012-06-10 11:42 沐阳 阅读(481) 评论(0) 推荐(0) 编辑
摘要: 该题题义很明确,看了题之后也会想到这时一个DP题目,问题在于如何来定义状态,以及建立合理的动态规划方程来求解这个问题。本题的输出是在泡到MM最多的情况下,花最少的时间。因此,时间的权限小于泡到MM的数量,为此我们可以用一个二维背包求解出最多能够泡到多少女生,这个并不难。再往后,如何保证时间是最少的呢,我的做法是再开一个数组,用来记录花费为 i “rmb”,j “rp”的最少时间,将时间数组的更新与二维背包求解最多MM数量做到同时更新,这样便能够保证一定是在泡到MM数量不减少的情况下的最少时间。代码如下:#include <cstdlib>#include <cstring&g 阅读全文
posted @ 2012-06-07 16:27 沐阳 阅读(293) 评论(0) 推荐(0) 编辑
摘要: 题义是两个人分别从左上角和右下角互相传递纸条,但是可以将问题转化为同时在左上角向下传递的两个纸条,求这两个不相交的路径的最大权值。TLE了,但总算是把思维的DP弄懂了,总是在路线重复上觉得这个dp方程存在问题,后面才恍悟,在两个纸团坐标相同的点的dp值总是为零的,因为它从头到尾都没有更新。定义的dp方程f[i][j][k][p]是指在1,1这个点同时抛的两个纸团的具体坐标(i,j)和(k,p),方程保证不更新两个点相同的值,方程是这样的:f[i,j,k,p]:=max{f[i-1,j,k-1,p]f[i-1,j,k,p-1]f[i,j-1,k-1,p]f[i,j-1,k,p-1] ... 阅读全文
posted @ 2012-06-06 22:25 沐阳 阅读(202) 评论(0) 推荐(0) 编辑
摘要: 该题算是一个暴力大表题了,给定了最多24根火柴棍,能够构成最大的数就是9992了,直接暴力。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <map>#include <algorithm>using namespace std;int N, make[10] = {6,2,5,5,4,5,6,3,7,6}, A, B, C, cnt; int ans[30] = {0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,8,9,6,9,29,3 阅读全文
posted @ 2012-06-06 22:13 沐阳 阅读(221) 评论(0) 推荐(0) 编辑
摘要: 前M-1个人是关于N-1个位置的全排列的情况下,M个人就能够做到他自己的位置了,而所有的请情况是M个人对于N位置的全排列的。用样本数除以样本空间就能够得到概率了。代码如下:#include <cstdlib>#include <cstdio>#include <cstring> using namespace std;int main(){ int N, M; while (scanf("%d %d", &N, &M) == 2) { printf("%.2lf\n", 1.0/N); } return 阅读全文
posted @ 2012-05-11 19:40 沐阳 阅读(432) 评论(0) 推荐(0) 编辑
上一页 1 ··· 40 41 42 43 44 45 46 47 48 ··· 66 下一页