题意
第一行输入一个正整数 \(T(1 \leq T \leq 1000)\),表示共有 \(T\) 组测试用例。对于每一组测试用例:
第一行输入三个正整数 \(n, m, k(1 \leq m \leq n \leq 3500, 0 \leq k \leq n - 1)\),且保证 \(n\) 之和不超过 \(3500\),第二行输入 \(n\) 个整数 \(a_i(1 \leq a_i \leq 10^9)\)。
总的有 \(n\) 个整数,每次会从两端任意取走其中一个数。你可以任意控制 \(k\) 次取数的方案,比如第 \(j\) 次取数可以控制取的数是当前剩余的数里最前面的一个。你要做的是找出一个 \(X\),使得无论如何取数,都能使得第 \(m\) 次取数不小于 \(X\)。输出 \(X\)。
题解
若控制第 \(j(j > m)\) 的取数方案,因为第 \(m\) 个数已经取过,显然对结果不会影响,因此只需要控制前 \(w = min(m - 1, k)\) 个数的取数方案。
不妨暴力枚举删除前 \(left\) 个数和后 \(right\) 个数,其中 \(0 \leq left, right = w - left \leq w\) 的情况下,在接下来的第 \((m - w)\) 次取数时能取到的数的最大值里的最小值。
参考代码
#include<bits/stdc++.h>
using namespace std;
constexpr int N = 3507;
int T, n, m, k;
int a[N];
void solve() {
cin >> n >> m >> k;
int ans = 1, w = min(m - 1, k);
m -= w + 1;
for (int i = 0; i < n; ++ i) cin >> a[i];
for (int i = 0; i <= w; ++ i) {
int left = i, right = n - w + i - 1;
int res = 1e9;
for (int j = 0; j <= m; ++ j) res = min(res, max(a[left + j], a[right - m + j]));
ans = max(ans, res);
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
cin >> T;
while (T --) {
solve();
}
return 0;
}
标签:Control,int,个数,Mind,codeforces,取数,leq,left
From: https://www.cnblogs.com/RomanLin/p/18588670