You are on page 1of 14

easy

normal
hard
杂题选讲 insane
BY 清华大学 茹逸中
normal
EllysChessboard(tc srm577)
给定一个 8*8 的棋盘
棋盘上有些点需要摆上棋子
摆上一颗棋子的代价等于这颗棋子到之前已经摆上的棋子的
manhattan 距离最大值
第一颗摆上的棋子代价为 0
求最小代价和
normal
EllysChessboard(tc srm577)
暴力?
棋子数量太多 ( 最多有 64 个 )
dp ?
状态太多不好记
如何缩减状态数量?
normal
EllysChessboard(tc srm577)
换个角度考虑问题
我们记 x’=x+y y’=x-y
x=(x’+y’)/2 y=(x’-y’)/2
那么两个点的距离 =
|(x’1-x’2+y’1-y’2)/2|+|(x’1-x’2+y’2-y’1)/2|=
max(abs(x’1-x’2)+abs(y’1-y’2))
于是我们只需要记已经摆上的棋子中的所有 x’,y’ 的最大和最小值就
好了
normal
EllysChessboard(tc srm577)
dp[x1][x2][y1][y2] 表示当前摆放的棋子中 x 最小 / 大的是 x1/x2,y 最
小 / 大的是 y1/y2 的最小代价和
转移:
每次从当前矩形扩展出一列或一行并计算这些格子上要摆的点的代
价和
hard
直线和圆
给定 N 条直线和 M 个圆,每个圆的半径都相同。求每条直线割到
了多少个圆。
n<=30000,m<=30000
hard
直线和圆
暴力?
差”一点点”
暴力算法似乎已经无法优化了,我们应该提出一个别的算法,即使
复杂度更高
hard
直线和圆
我们维护每个点到一条直线的距离 ( 这里的距离是有符号的,在直
线上方为正,下方为负 ) 的单调序列。
我们发现,当这条直线的斜率不断变化时,只有当它的斜率与某两
个点连线的斜率相等时,序列才会发生变化,变化的方式是交换这
两个点的位置 ( 可以证明这两个点在序列中一定是相邻的 ) 。
因此这个算法就是将所有点之间两两连线的斜率算出来排序,然后
扫一遍,边扫边二分询问即可。
hard
直线和圆
这个算法的复杂度比较高 O((n^2+m)logn)
但是我们可以对圆心进行分块
复杂度降低为了 O((n+m)*n^0.5*logn)
虽然还是很慢,但是至少比暴力快一点……
insane
摸墙 (acm2012World Final)
QDC 被关在了一个凸多边形的小黑屋里。
问 QDC 从当前位置 P 开始,摸完所有的墙,再回到 P 所需要走过
的路程最少是多少。
P 保证严格在多边形内
QDC 被认为是一个点
当 QDC 在多边形的顶点上时,认为他同时摸到了这两堵墙。
n<=100 T<=20
insane
摸墙 (acm2012World Final)
入手比较难 ...
我们先来做一道小学数学竞赛题
有一条直线和两个在这条直线同一侧的点 AB ,要求直线上的一个
点 P 使得 AP+BP 最小
insane
摸墙 (acm2012World Final)
如果有两条边呢?
作两次反射就好了
insane
摸墙 (acm2012World Final)
但是,如果交点在多边形外怎么办?
由于距离和关于点的位置是单调的,所以这个时候我们应该让他走
到多边形的顶点上
然后呢?
DP !
insane
摸墙 (acm2012World Final)
首先有个比较显然的结论,最优方案中路径是不会相交的,一定是
按照某个顺序依次经过每条边。
又因为路径是可逆的,所以我们可以假设是按顺时针顺序。
先枚举起点,然后用 dp[i] 表示走到第 i 个顶点时的最小长度。转移
时枚举下次到达的顶点 ( 或终点 )
复杂度 O(n^3)

You might also like