题意
有 \(n\) 栋建筑,第 \(i\) 栋建筑的高度为 \(a_i\),一座建筑能从左侧看到仅当它左侧的建筑高度都小于它,问你最少需要爆破几座房子,才能使第 \(l\) 座房子成为能看到的第 \(k\) 高建筑。
\(n\le 10^5,k\le 10\)。
思路
首先 \(l\) 要能被看到,因此先把 \(l\) 左边高度大于等于它的全炸了。
由于要求第 \(k\) 高,左边就不用考虑了。
假设 \(l\) 为最左边的建筑,问题就变为了有 \(k\) 栋能看见的建筑需要炸的最小数量。
设 \(f_{i,j,k}\) 表示第 \([1,i]\) 栋建筑有 \(j\) 栋能看见的建筑,最高的建筑为 \(k\) 需要炸的最少数量。
则有 \(f_{i,j,k}=\min\{f_{i-1,j,k}+[a_k<a_i],f_{i-1,j-1,k'}(k=i,a_k>a_k')\}\),答案即为 \(f_{n,k,k'}\)。
\(f\) 的第 \(i\) 维可以使用滚动数组优化。
我们记录下 \(a_i\) 的原始顺序,再把 \(a_i\) 排序,这样对于 \(f_{i,j,k}=f_{i-1,j,k}+[a_k<a_i]\) 就变为了区间加法。
对于 \(f_{i,j,k}=\min\{f_{i-1,j-1,k'}\} \ (k=i,a_k>a_k')\),我们同样可以区间查询最小值。
区间修改求最小值,使用线段树维护 \(f\),可以通过。