随笔分类 -  ACM_搜索

摘要:题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=29358 状态虽然很多,但是非常稀疏,dfs搜索然后剪下枝。。 或者DP,f[i][j][k]表示前 i 个物品能否到达第一个背包和第二个背包容量分别为 j 和 k 的状态,然后判断第3个背包是否能装下剩下的。f[i][j][k]=f[i-1][j][k] | f[i-1][j-v[i]][k] | f[i-1][j][k-v[i]].. 搜索: 1 //STATUS:C++_AC_10MS_1308KB 2 #include 3 #include 4 #include ... 阅读全文
posted @ 2013-08-26 10:38 zhsl 阅读(259) 评论(0) 推荐(0)
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4665 本题的2-SAT建图颇为复杂,有时间再来填坑(自己写的一直挂着,标程建图太复杂了)。。。然后用暴力搜索,用一个栈保存第一个序列就可以了,因为题目是SPG,并且重复的最多只有四个,所以搜索很好过。。 1 //STATUS:C++_AC_62MS_276KB 2 #include 3 #include 4 #include 5 //#include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #incl... 阅读全文
posted @ 2013-08-10 00:25 zhsl 阅读(431) 评论(4) 推荐(0)
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628 数据不大,枚举本质。首先对枚举出回文串,然后用DP或者搜索,这里因为层数不多,用bfs比较好,或者用IDA*。。。 1 //STATUS:C++_AC_140MS_780KB 2 #include 3 #include 4 #include 5 //#include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include... 阅读全文
posted @ 2013-08-02 21:13 zhsl 阅读(250) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=2286 IDA*对于最优解层数小,每次扩展状态多的时候是一个杀手锏啊。IDA*就是一个加了层数限制depth的DFS,超过了限制就不在搜索下去,如果在当前层数没有搜到目标状态,就加大层数限制depth,这里还只是一个IDA算法,并不是A*的。当然我们可以用A*的估计函数去剪枝,如果当前深度d+h()>depth的时候就可以不再搜索下去了,这样就是IDA*了。 对于这道题,我们把状态用一维数组存储,然后对每个元素设定相应的编号: 0 1 2 3 4 5 ... 阅读全文
posted @ 2013-04-30 22:10 zhsl 阅读(495) 评论(0) 推荐(0)
摘要:八数码问题,对于一般的数据,BFS+逆序对HASH就可以解决了,或者双广搜索。进一步的话就是A*优化,A*的启发函数有以下两种:1,不在相应位置的格子数目; 2,不在相应位置的曼哈顿距离之和;显然第二种的效率比较高。一中兼顾效率,写起来有方便的算法就是IDA*,因为不要判重,而且是DFS,代码量小。还有猥琐点的方式就是从目标状态向所有状态扩展打表。。。 对于八数码问题,还有一个重要剪枝,那就是逆数对的剪枝,如果开始状态的逆数对数目是奇数则必无解,否则一定有解。因为对于目标状态的逆序对是0,即偶数,而操作只能与0交换,而0是不会影响结果的,只有于0交换的数会影响结果,但是那个数移动也会没有... 阅读全文
posted @ 2013-04-30 21:44 zhsl 阅读(500) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=3590 自己暴力给水过去了,不过效率有点低。题目要求的就是给一个数n,要你求出一种方案,一些和为n的数的最小公倍数最大。题目数据量不大,容易想到用暴力的办法求出所用情况,然后比较就可以了,然后再剪下枝就可以过了。不过有更好的方法。和为n的数的最大公倍数可以用DP求出来:f[i][j]表示和为i的数划分为j个循环节时的最大公倍数,则f[i][j]=max{f[i-k][j-1] | j-1<=k<i-1};然后就是求最小的置换了。设n的最大公倍数是m,则有p1^k1*p2^k2*……*pn^kn=m,显然有p1^k1+p 阅读全文
posted @ 2013-03-04 23:26 zhsl 阅读(284) 评论(0) 推荐(0)
摘要:题目链接:http://poj.org/problem?id=3295 水题本质。数据量小,直接枚举判断即可。但要注意在搜索的时候,如果进行逻辑运算&&和||时, 存在短路特性的!比如,dfs(cur+1)||dfs(cur+2),如果dfs(cur+1)==ture,那么dfs(cur+2)就不会访问了,所以导致cur的下标访问出错,那么我们在写这种表达式的时候,把dfs分别赋值然后再去进行逻辑判断是一种好习惯,可以减少不必要的错误!我开始这里没有注意好,wa了!然后还提一下,C++是从逻辑判断符的右边开始判断的,而G++是从左边开始的,也就是这题有些人C++和G++不能同时 阅读全文
posted @ 2012-12-16 15:40 zhsl 阅读(247) 评论(0) 推荐(0)