vjudge二分实战
D:
大概的题意:4组数据,每组数据选出一个数,求出加和为0的所有的方式。
思路:感觉跟老师在课上讲的一个很像,类比与计算两个数的和为0,每次枚举一个数,在另一个区间寻找答案。我们可以把4组数据分为两组,一组为前两组的和,一组为后两组的和,在寻找即可。排序后,感觉可以用upper_bound和lower_bound简化代码。lower_bound:寻找等于要找的数的第一个位置。
upper_bound:寻找大于要找的数的第一个位置。
每次枚举前两个数组和时,可以直接调用这两个函数计算。
for(i=1;i<=t;i++)
{
long long p=lower_bound(ab+1,ab+t+1,-cd[i])-ab;//在排序好的数组ab中寻找等于前两个数的和的相反数的位置
if(ab[p]==-cd[i])
ans+= upper_bound(ab+1,ab+1+t,-cd[i])-ab - p;//答案每次加上等于(前两个数的和的数)的个数
}
G:
最大值最小化的问题
思路:二分解决枚举的最小值是每个数中的最大值,最大值是所有数的总和。因为每次枚举的数肯定是大于等于所有数中的最大值的,所以最多可以分成N个集合,然后在算出最小的集合,最小的集合数量就是每一个集合有尽可能多的数的集合数。用mid枚举数的和,用cnt记录该mid需要多少区间(组),k记录暂时的和,当k加上现在的数后大于当前的mid时 (因为遍历的是最大和),该数不能加到当前区间中,而是加到下一区间中,此时记录的区间cnt++,遍历完之后,如果当前的mid需要的区间数即cnt>m,说明该mid偏小,反之偏大。
搜索
搜索算法是利用计算机的高性能来有目的的穷举一个问题解空间的部分或所有的可能情况,从而求出问题的解的一种方法。相比于单纯的枚举算法有了一定的方向性和目标性。算法在解的空间里,从一个状态转移到其他状态,这样进行下去,将解的空间中的状态遍历,找到答案。搜索算法需要在指数量级的繁杂的可选对象中搜索某个具有特定性质的解,而且,求解这些问题似乎没有什么捷径可行。
深度优先搜索DFS
思路:从初始状态,利用规则一层一层的搜索,从任意一个节点到下层的每一个节点,搜索完后返回上一层,重新选择上层中的其他节点。
一般采用递归的方式实现。
fun(int setp,now当前状态)
{
begin
可以加结束条件
从当前状态循环到下一个状态next
if(状态next合法)
fun(setp+1,next下一个状态)
end
}