随笔分类 -  搜索

HDU 4705 Y 树形枚举
摘要:树形枚举--搜索题目描述:给你一棵树,要在一条简单路径上选3个不同的点构成一个集合,问能构成多少个不同的集合。解法:枚举所有结点,假设某个结点有n棵子树,每棵子树的结点个数分别为s1,s2,````sn.那么在选中该结点后,剩下的两个结点从子树上选,考虑顺序,则有方案数ans=s1*(sum(si)-s1)+s2*(sum(si)-s2)+```+sn*(sum(si)-sn),化简得ans=sum(si)^2-sum(si^2).实际上,另外两个点选了(1,2)和(2,1)对于集合{a,b,c}而言是一样的,所以方案数应该为ans/2。而一个结点的子节点的总和为n-1。只要求sum(si^2 阅读全文

posted @ 2013-08-25 20:33 allh123 阅读(158) 评论(0) 推荐(0)

POJ 3716 Cow Bowling 数字三角形 简单DP
摘要:照抄刘汝佳的《算法竞赛入门经典》(较薄的那本)P159 数字三角形两种写法,一个是记忆化搜索,一个是DP,其实之所以要用DP是因为解这个题时出现了大量重叠的子问题用d(i,j)记录从第i 行,第j列出发(从上往下)能得到的最大和(包括自己)转移方程为d(i,j) = a(i,j) + max(d(i+1,j) , d(i+1,j+1));还有一个问题就是关于#define max(a,b) a<b?a:b的用法如果写这样的式子 t = a + max(c,d),怀疑会出错,因为下面的递推式我本来没有写max()函数而是用的这个宏定义,但是就错了,一直出不来正确的结果,还不符合" 阅读全文

posted @ 2013-05-09 19:42 allh123 阅读(275) 评论(0) 推荐(0)

DFS HDU 1518 Square
摘要:因为n<=20,较小,用DFS,但是要剪枝,不然就TLE这个题是校队讨论时ZZM说的,然后里面有讲到一种错误的思路,用0-1背包恰好背满边长,边长的2倍 ,边长的三倍,边长的四倍事实上,如果数据是7 7 2 1 7 8就是一个反例,每种都能背满,但是无法构成四边形。然后我自己先写了一个DFS,用四个数d1,d2,d3,d4来存状态,对于每根棍子,有四种可能,分别是放d1,d2,d3,d4里,再往里搜,回退的时候,d1,d2,d3,d4回到原来的状态。一个剪枝是当d1,d2,d3,d4中出现大于边长的值就return,不往下搜了。还有就是已经搜到可行解了,也不搜了。这样最坏情况下复杂度为O 阅读全文

posted @ 2013-04-25 18:56 allh123 阅读(179) 评论(0) 推荐(0)

UESTC OJ 1824 Judgment Day 递归搜索
摘要:这题就是写个DFS,搞定,比赛的时候没有看到N<=10,不敢暴力,因为这个的复杂度为2^n.看题一定要认真啊啊啊啊!!!!!枚举所有的可能,每个人都有两种情况,一是spell他的名字,一个是不spell.所以一共有2^n种情况,当然,名字拼不出来就只有一种,就是不spell.简单吧,用递归写,我一般都把递归写的叫DFS。贴代码:View Code 1 #include <cstdio> 2 #include <cstring> 3 int n; 4 int num[30]; 5 int pn[11][30]; 6 int max; 7 void dfs(int x 阅读全文

posted @ 2013-04-24 21:25 allh123 阅读(308) 评论(0) 推荐(1)

15个球,6个位置,求按递增序列输出不同的摆法 DFS
摘要:贴代码:View Code 1 #include <cstdio> 2 #define MAXN 160000 3 int a[MAXN][6]; 4 int cur; 5 int st[6]; 6 //表示要去第i个位置放球,还有sum个球没放 7 void DFS(int i,int sum) 8 { 9 int j,k;10 if(i==5)//放最后一个位置,那么直接把剩下的球都放在该位置上11 {12 st[i] = sum;13 for(j=0; j<6; ++j) //放数组里保存起来14 a[c... 阅读全文

posted @ 2013-04-12 10:49 allh123 阅读(341) 评论(0) 推荐(0)

八皇后问题 DFS,回溯剪枝 //http://poj.grids.cn/practice/2698
摘要:就是DFS,一出现同行,同列或同对角线,就不往下搜了,就叫剪枝,然后一到出现一个可行解,输出来。记得再递归调用回退的时候要“恢复现场”贴代码:View Code 1 //http://poj.grids.cn/practice/2698 2 #include <cstdio> 3 #include <cstring> 4 bool a[10][10]; 5 int cur=0; 6 //开始考虑放第i行 7 void DFS(int i) 8 { 9 int j,k;10 if(i == 8)//得到一个可行解11 {12 printf("No. %d... 阅读全文

posted @ 2013-04-12 00:36 allh123 阅读(476) 评论(0) 推荐(0)

ZOJ 1136 Multiple BFS 取模 POJ 1465
摘要:该题的关键是如果a%n = x;则(a*10+b)%n == (x*10+b)%n。例如你要算123456789%3,你只需算((12345678%n)*10+9)%3。想法是把给你的数字先排序,然后扩展,这样能保证你拓展出的数是以递增序列出现的。按示例所示,给你数字1,7,0,你可以拓展出10,11,17;70,71,77;从拓展出的六个新的数,每个数又能拓展出M(这里的M为3)个。然后要优化处理,算所谓的剪枝吧。拓展出的数模n的余数等于原数的余数*10+增加的数,再模n.如果新数的余数已经出现过,就不入队列了,因为该数没有被拓展的必要(已经有一个比它小的数用来拓展)。如果出现某数的余数为0 阅读全文

posted @ 2013-03-24 17:48 allh123 阅读(308) 评论(2) 推荐(0)

z0j1008Gnome Tetravex
摘要:该题是找满足条件的摆法,直接DFS会超时,关键是压缩存储,同一种正方形只存一次,再DFS,然后搜到一种成功的就要退出,不要把所有可能的摆法都搜完,不然也会超时。初始化种类数不要忘记。View Code 1 #include <cstdio> 2 #include <cstring> 3 bool flag ; //成功标志 4 int n,kinds; //正方形的个数为n*n,种类为kinds 5 struct square 6 { 7 int top,bottom,left,right; 8 int num; //该类正方行的个数 9 } rect[26];//记录 阅读全文

posted @ 2013-03-15 16:57 allh123 阅读(170) 评论(0) 推荐(0)

导航