灌溉草场,线性DP,POJ2373
- 一片草场上有长度为L,且为偶数的线段
- John的头奶牛在操场上沿着这条线段吃草
- 每头奶牛的活动范围是一个开区间,都是整数
- 不同奶牛活动范围有重叠
- 现在要安装若干个可调节的喷水头灌溉草场,每个喷水头的工作半径在可中调节
- 要求喷水头满足下列要求
- 线段上每个整点恰好位于一个喷水头的喷洒范围内
- 每头奶牛的活动范围要位于一个喷水头的喷洒范围
- 任何喷水头的喷洒范围不得超过线段两端
求John最少要安装多少个喷水头,若无法刚好安装则输出
问题分析
- 从左端点向右端点安装喷水头,设表示:所安装喷水头的喷洒范围恰好覆盖直线上的区间时,最少需要多少个喷水头
- 显然,X满足:
- X为偶数
- X所在位置不会出现奶牛,即不属于任何一个
- 当时,存在且满足上述三个条件使得
解题思路
递推计算
- 是奇数
- 处可能有奶牛出没
- ,且位于任何奶牛活动范围之外
位于任何奶牛的活动范围之外,且X>2B
优化
位于任何奶牛的活动范围之外,且X>2B。
对于此转移中的每个求都要便利区间,太慢
- 所以快速找到此区间使得最小的元素是解题的关键。
可以用堆来优化哦
- 使用C++的STL中的priority_queue
- 求时,我们维护一个小根堆,保证堆中包含所有的所对应的值,这样操作时间就从扫区间的级别变成了级别了
- 求解对应的时,不允许堆中出现坐标大于的点,这样的点不能用来转移,又不能抛弃之,因为它可能对求后续点的值有用
- 堆中可以出现坐标小于的点,若其出现在对头,则抛弃
- 求出点的值后,将放入堆,为求作准备
- 堆中点坐标皆为偶数
代码
|
Author: Sulfur6
Origin: http://sulfur6.github.io
Link: http://sulfur6.github.io/pour-the-grass/
本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可