USACO 3.1.6 Stamps 解题报告
这一题我就用的动态规划:f[l]=max(f[l], f[l – num[i]]); f[0] = 1; l是总面额,i是第num[i]个邮票的面值,但是超时,没想到别的算法,怎么办?找地方剪枝,见了三处就AC了,这效果立竿见影啊!后来到网上看了下,还有更快的方法,我是三重循环,它是二重循环,用f[……]
这一题我就用的动态规划:f[l]=max(f[l], f[l – num[i]]); f[0] = 1; l是总面额,i是第num[i]个邮票的面值,但是超时,没想到别的算法,怎么办?找地方剪枝,见了三处就AC了,这效果立竿见影啊!后来到网上看了下,还有更快的方法,我是三重循环,它是二重循环,用f[……]
这个题目其实算法还是比较简单,关键是怎么保存这些数字,其实啊,最好的保存方法就是二进制,且增加前缀1,比如0就是二进制10即十进制2,想必聪明的你要问为什么需要前缀1了,为什么呢?如果不要的话那么0和00都是二进制的0,怎么区分呢?所以用前缀1,那么最大的话也就是12位的1加一个前缀1,2^13=8[……]
这个题目用数组来记录纸的每一个颜色是不可能的,无论是时间上还是空间上都无法忍受,就只能用具体的矩形来表示了,比如底纸,就是一张(0, 0, a, b, 1)的底纸,代表起始坐标是(0, 0)末坐标是(a, b)颜色是1,将它加入数组作为第一个元素,当添加进了一个新的矩形的时候,将数组所有的元素都和这[……]
这个题目属于什么算法呢?我才疏学浅不知道,反正就是用num来记录丑数,假设1为丑数,代码实现会简单些,那么丑数必定就等于另外一个丑数乘以一个素数,那么再一个个的按大小找到前n个丑数,就可以了。 时间的话大概是O(nm),对每个素数都记录该和哪个丑数相乘start[i],如果sub[i](第i个素数[……]
这题和第三章第一题一样,标准的无限01背包,直接把代码放进去就可以了,代码: / LANG: C ID: yylogoo1 PROG: inflate / #include int f[10001]; #define max(a, b) ((a)<(b)?(a):(b)) int main[......]
这题的话,是最小生成树的标准题,但是最小生成树我不记得写了,后来想起来了之后发现这个二叉堆实现很麻烦,就看看标称的二叉堆是怎么实现的,结果标称直接暴力就是,呵呵,感觉有点投机取巧,因为数据小所以这样。 晚点捉摸下二叉堆的实现,先把这题的代码贴上来(暴力搜的) / LANG: C ID: yylog[......]
这题的话,其实也好说,就是利用余数进行判断,看代码吧: de lang="C">/ LANG: C ID: yylogoo1 PROG: fracdec / #include int num[100001]; int mod[100001]; char str[77];[……]
这一题其实很简单,只是有个陷阱,考验你们细心与否,就是两个牧场之间可能不只有一条路径,所以这里注意一下就不会出大问题,代码如下所示: de lang="c">/ LANG: C ID: yylogoo1 PROG: comehome / #include #define[……]
这个题目涉及的算法真的好多好多,一下子还真摸不着头脑,但摸着没摸着都先听我说。 首先要把链接在一起的那些牧区之间的距离算出来(勾股定理),然后要把各个牧场的牧区标示出来(洪水填充),这样就能进行下一步了,再把各个节点之间的距离算出来,用floyd-warshall算法,O(n^3)的那个算法,然后[……]
题目看了之后容易发现就是广搜,从两个入口对全图进行广搜,搜到最后一个所需要的路程就是答案,广搜实现一点儿也不难,我的实现感觉还是比较好的,用一个宏和一个函数实现这个功能,然后用数字代表前进的方向,0:北,1:南,2:西,3:东。 但这题难的地方我觉得是把图转化成数据和寻找入口,其实难也不难,只是希[……]