一个N*M棋盘每格有一个数字,用p个同半径的已知圆心的圆覆盖棋盘,求最小半径使得覆盖方格数字和不少于k。
1≤n,m≤1000,1≤p≤109
求一些圆怎么覆盖棋盘,不如考虑方格怎么会被圆覆盖,所以可以求离方格最近的圆心。
先考虑一行内。求一行内每个方格距离最近的圆心的距离的平方,显然正反扫两遍即可。
令
g[i][j]
表示第i行到(i,j)最近圆心距离的平方。
然后
f[i][j]=min{g[k][j]+(i−k)2,k≤i}
那么
f[i][j]
就是在
1 i
行内距离
(i,j)
最近的距离了,倒过来做一下就可以知道全部得了。
但是
f[i][j]
要
O(n3)
才可求得,考虑优化。发现形式是经典的斜率优化(实际上似乎很多求欧几里得距离的DP都可以斜率优化)。然后针对每列开一个单调队列即可。
其实KD树可能可以水很多分吧。。。
GDSOI T2。