ARC098 E - Range Minimum Queries

問題

長さnの数列に対し「長さkの区間を選び、その中の最小の要素を取り除く」という操作をq回行う
取り除いた要素の最大値をx、最小値をyとしてx-yの最小値を求める

解法

最小値を決め打ちして最大値を最小化する方針
最小値をyにするには、y未満の数字を含む区間を選ぶことはできない
そこでy未満の要素を全て消すと、元の数列に穴が空き、いくつかの独立な区間に分かれる
区間からは、区間の長さをmとすると最大で、その区間の中で小さい方からm-k+1個の数字を取り除ける
これらの取り除ける数字全ての中でq番目に小さい値をxにするのが最善

実装

しゃくとり法っぽく

int n, k, q, a[2020], res = inf;

int main() {
	cin >> n >> k >> q;
	rep(i,n) cin >> a[i];
	rep(i,n) {
		vector<int> mn;
		rep(l,n) if (a[i]<=a[l]) {
			int r = l;
			vector<int> t;
			while (r<n && a[i]<=a[r]) t.push_back(a[r++]);
			sort(all(t));
			rep(j,(int)t.size()-k+1) mn.push_back(t[j]);
			l = r-1;
		}
		sort(all(mn));
		if (mn.size()>=q) chmin(res, mn[q-1]-a[i]);
	}
	cout << res;
}