zoukankan      html  css  js  c++  java
  • 分治算法例题

    例0

    u  二维平面上有一些点。有Q个询问,每个询问问横坐标不超过x,纵坐标不超过y的点的数目。可以离线。

    u  这题的另一种形式是求逆序对。

    u  正解:把所有点和询问排序,然后用树状数组即可求解。

    例1

    u  在一个初始为空的二维平面上,要求支持2种操作:

    u  插入一个点

    u  查询一个矩形内点的个数

    u  坐标<=2*10^6

    u  操作1数量<=160000

    u  操作2数量<=10000

    u  问题可以转化为:给定一个三维平面,每次求三维坐标在一个范围内的点的个数。

    u  按x排序,然后考虑分治。

    u  两边内部的答案可以递归计算。我们需要计算左边的点对右边的询问的贡献。

    u  分别处理两边后,我们可以把左右按y排序,依次处理。对于x在左半边的点,按z坐标插入树状数组中,这样我们就可以快速统计出x在右半边的询问的答案了。

    u  排序可以用归并来完成。

    u  时间复杂度:O(nlog^2n)

    u  这个算法是由cdq提出的,所以叫cdq分治。

    例2

    u  给定二维平面上的n个点,求最近点对

    u  n<=10^5

    u  考虑分治。

    u  按x坐标排序,然后先求出左边一半和右边一半的解。

    u  假设当前答案为d,那么找出距离中线(mid)小于d的点。

    u  将这些点按y坐标排序。对于每个点,只需要求它和它上面8个点的距离并更新答案即可。

    u  想一想,为什么?

    u  事实上,这个数字还可以缩小。有兴趣的同学可以自行思考。

    例5

    u  N个物品有单价,收益,限购次数,第i个询问用w[i]的钱,在禁止购买ban[i]的情况下,能获得的最大收益

    u  N<=1000    Q<=10^6    w[i]<=1000

    u  考虑分治

    u  对于全部的物品,对于右边一半的物品,左边一半的物品都对它有贡献

    u  solve(l,r)表示,当前维护dp数组,记录的答案是出去[l,r]外的物品的答案

    u  solve(l,mid)时用[mid+1,r]内的物品转移dp数组

    u  当l=r时,将所有ban=l=r的询问一起(查dp数组)求答案

    u  给定一张无向图(n<=700),每条边都有两个边权A和B

    u  求一棵生成树,使得(所有边的A边权之和)*(所有边的B之和最小)

    u  最小乘积模型:

    u  考虑用二维平面上的点表示每一个解,其中x坐标表示其中一维权值和,y坐标表示其中另一维权值和。

    u  每一个解对应的答案即为该点所在的反比例函数的k值。

    u  很显然,最优解一定在凸壳上。

    u  分治地去求这个凸壳。先求出x最小的解L,y最小的解R。

    u  找到离AB这条直线最远(靠近原点方向)的解Mid。(想一想,怎么求?)

    u  然后不停地分治,直到Mid离AB的距离为0。

    u  每次求出一个新解时,就更新答案。

    u  复杂度:玄学(n不大不小)

    例1 cogs1752

    例2 hdu1007

    例5 bzoj3163

    例6 bzoj2395

  • 相关阅读:
    Java实现 蓝桥杯 算法训练 画图(暴力)
    Java实现 蓝桥杯 算法训练 画图(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 Cowboys
    Java实现 蓝桥杯 算法训练 Cowboys
    55. Jump Game
    54. Spiral Matrix
    50. Pow(x, n)
  • 原文地址:https://www.cnblogs.com/ZYBGMZL/p/6796248.html
Copyright © 2011-2022 走看看