[洛谷P4563]守卫
题目 传送门 思路 一开始感觉是凸包啥的……然后惨痛爆零…… 对于一个区间 [ l , r ] [l,r] [ l , r ] ,发现 r r r 必须有一个守卫(否则就没法监视 r r r 号亭子)。 然后 r r r 能看到一些亭子。剩下一些亭子。 红色的就是看不到的亭子(被右边的蓝色亭子挡住了)。蓝色的是看的到的。 由于守卫可以 随意抬头但不能低头 ,所以能够看到多少,就取决于 能看到多低 。 很明显, r r r 号亭子看不到的,红色亭子也看不到,因为绿色的线比红色的线低。 所以每两个看的到的亭子之间的那一段区间,是 相互独立 的。 于是使用区间 D P \mathbb{DP} D P 。对于某个固定的右端点,左端点不断左移,可以 O ( 1 ) O(1) O ( 1 ) 维护 r r r 能够看到的最矮的(也就是最左边的、能看到的)。那么就可以做到 O ( 1 ) O(1) O ( 1 ) 转移了。总复杂度 O ( n 2 ) O(n^2) O ( n 2 ) 。 转移时要注意,由于最近的蓝色亭子是可以被看到的,要考虑是否在蓝色亭子安排守卫。 代码 # include <cstdio> # include <iostream> # include <vector> using namespace std ; const int MaxN = 5000 ; int dp [