1.4深度优先搜索
算法理解
将每种状态看成一个节点,基于树上的搜索
剪枝技巧
正确,准确,高效
1.优化搜索顺序
2.排除等效冗杂
3.可行性剪枝
如果前面是死胡同,就不要再走了
4.最优性剪枝
当前代价超过搜到过最优的答案
5.记忆化
T1:
暴力搜索,一半的拔河人数分配情况
T2:
暴力搜索,没有剪枝
T3:
卡了好久,枚举每个字母对应的数,考虑剪枝优化,先从最低位的字母开始搜起,其次,每赋值一个字母,就进行判断:
1.本位及本位之前的字母都已赋值过,就正常递推过来看正不正确
2.本位之前有不知道的字母,本位如果
\[( a + b )\%n \ne c \&\& ( a + b + 1 ) \%n \ne c
\]
就一定不对
3.只有n位,若第n位上还要进1则不对
T4:(2h30min)
剪枝魔怔题
上界剪枝:如果上层的蛋糕都按照最小体积还是不行或都按侧面积最小值还大于ans的话则返回掉
下界剪枝:注和上界剪枝区别,若此后都按照本层方案选仍达不到体积n,肯定不行
枚举顺序:因为侧面积为 \(2*r*h\) ,体积为 \(r*r*h\) 所以体积一定的情况下 r 越大,侧面积越小,r从大到小枚举
T5:
折半搜索,将要dfs的数分成两半,dfs出每组的每一种情况,前一半暴力枚举,后一半二分找出最大组合答案
T6:
最后做的一道题,首先因为它规定了枚举的层数15层,所以不能用dfs要不然会无限搜,考虑IDDFS
T7:
考虑正约数公式(懒得打了),枚举50以内的质数,毕竟因为用较小的质数筛是更优的,至于为什么是50以内的呢,我也没想明白,然后再dfs枚举下一个质数是多少
T8:
只要不考虑翻转就行了,因为翻转完再折和没翻转是等价的,判定答案时翻一下就好了
ps:对于没有结束符的题可以
while(scanf("%d",&n)!=EOF)
或
while(cin>>n)
++ps:要想在dfs中传递一个数组,只可以传递那种在每一次dfs时可以返回的修改,即做完之后要改回来,若不需要传递,又害怕被下一层dfs影响,可以定义循环内的数组