题目链接:https://codeforces.com/contest/1291
You and your n−1 friends have found an array of integers a1,a2,…,an. You have decided to share it in the following way: All n of you stand in a line in a particular order. Each minute, the person at the front of the line chooses either the first or the last element of the array, removes it, and keeps it for himself. He then gets out of line, and the next person in line continues the process.
You are standing in the m-th position in the line. Before the process starts, you may choose up to k different people in the line, and persuade them to always take either the first or the last element in the array on their turn (for each person his own choice, not necessarily equal for all people), no matter what the elements themselves are. Once the process starts, you cannot persuade any more people, and you cannot change the choices for the people you already persuaded.
Suppose that you’re doing your choices optimally. What is the greatest integer x such that, no matter what are the choices of the friends you didn’t choose to control, the element you will take from the array will be greater than or equal to x?
Please note that the friends you don’t control may do their choice arbitrarily, and they will not necessarily take the biggest element available.
Input
The input consists of multiple test cases. The first line contains a single integer t (1≤t≤1000) — the number of test cases. The description of the test cases follows.
The first line of each test case contains three space-separated integers n, m and k (1≤m≤n≤3500, 0≤k≤n−1) — the number of elements in the array, your position in line and the number of people whose choices you can fix.
The second line of each test case contains n positive integers a1,a2,…,an (1≤ai≤109) — elements of the array.
It is guaranteed that the sum of n over all test cases does not exceed 3500.
Output
For each test case, print the largest integer x such that you can guarantee to obtain at least x.
Example
inputCopy
4
6 4 2
2 9 2 3 8 5
4 4 1
2 13 60 4
4 1 3
1 2 2 1
2 2 0
1 2
outputCopy
8
4
1
1
Note
In the first test case, an optimal strategy is to force the first person to take the last element and the second person to take the first element.
the first person will take the last element (5) because he or she was forced by you to take the last element. After this turn the remaining array will be [2,9,2,3,8];
the second person will take the first element (2) because he or she was forced by you to take the first element. After this turn the remaining array will be [9,2,3,8];
if the third person will choose to take the first element (9), at your turn the remaining array will be [2,3,8] and you will take 8 (the last element);
if the third person will choose to take the last element (8), at your turn the remaining array will be [9,2,3] and you will take 9 (the first element).
Thus, this strategy guarantees to end up with at least 8. We can prove that there is no strategy that guarantees to end up with at least 9. Hence, the answer is 8.
In the second test case, an optimal strategy is to force the first person to take the first element. Then, in the worst case, both the second and the third person will take the first element: you will end up with 4.
题意
有 n 个人,排成一排,你站在 m 位置。
恰巧有 n 个数,也排成一排
按照编号,每个人可以移除数列首位或者末尾的数,然后自己保留
你可以说服最多 k 人,让他们选择数列首位或者末尾
然后你未说服的人,移除是随机的,不一定移除最大的数
要求:你的选择是最优的,然后在所有情况下自己保留的数都>=x,让你求出 x,
思路
因为 n 不是很大,可以直接贪心……弱鸡只为贪心
优先说服前 k 个人,强行找解释
肯定是劝说排在你前面的 k 个人,这个毋庸置疑
然后的话,你未劝说的人是随机选择的,
假设你劝说[2,k+1]个人都选首,那么就分为 [1,k+1]都选首,和 1 选尾 [2,k+1]选首,这两种情况
假设你劝说[1,k]个人都选首,那么就分为[1,k+1]都选首,和 k+1 选尾 [1,k]选首,这两种情况
他们之间有重合的地方
我们不会讨论你劝说的人首尾情况,我们只看未劝说的人(截至到你)的可选择情况
那么说服前 k 个人,应该是和说服[1,m)之间 k 个人的情况是一致的。
那么很明显 k 要分类讨论一下,
当 k>=m-1 时
你劝说前 k 个人,你可以拿你想拿的任何数,但是这个数的范围是 [l,r]
其中 l∈[1,m],r∈[n-m+1,n]
也就是,轮到你选择的时候:
l | 1 | 2 | 3 | 4 | … | m |
---|---|---|---|---|---|---|
r | n-m+1 | n-m | n-m-1 | n-m-2 | … | n |
l=1,r=n-m+1的含义:你劝说前 m-1 的人都取尾,那么你可以选此时的首 1 或者 尾 n-m+1
这时选择的主动权在你手上
你可以选择表格中的任意l,r,考虑最优,取max。
int ans=0;
for(int i=1;i<=m;i++){
ans=max(ans,b[i]);
}
for(int i=n;i>=n-m+1;i--){
ans=max(ans,b[i]);
}
printf("%d\n",ans);
当 k<m-1 时
你劝说前 k 个人拿取之后,后面的人的选取区间是 [l,r]
其中 l∈[1,k+1],r∈[n-k,n]
也就是,轮到k+1选择的时候:
l | 1 | 2 | 3 | 4 | … | k+1 |
---|---|---|---|---|---|---|
r | n-k | n-k-1 | n-k-2 | n-k-3 | … | n |
l=1,r=n-k的含义:你劝说前 k 的人都取尾,那么第k+1人可以选此时的首 1 或者 尾 n-k
那么,再经过[k+1,m)这些人选取后,你能选取的空间是 [nl,nr]
其中 nl∈[l,r-(n-m)],r∈[l+n-m,r]
也就是,轮到你选择的时候:
nl | l | l+1 | l+2 | l+3 | … | r-(n-m) |
---|---|---|---|---|---|---|
nr | l+n-m | l+n-m+1 | l+n-m+2 | l+n-m+3 | … | r |
以为,轮到你选择的时候,还剩下 n-m+1个人 没选择,
nl=l,nr=l+n-m的含义:[k+1,m)这些人都选择的尾,那么你可以选此时的首 l 或者 尾 l+n-m
但是此时的主动权不在你手上
他们是随机选取,所以取 min。
int ans=0;
for(int l=1;l<=k+1;l++){
int r=n-(k-l+1);
int res=0x3f3f3f3f;
for(int nl=l;nl<=r-(n-m);nl++){
int nr=nl+n-m;
res=min(res,max(b[nl],b[nr]));
}
ans=max(ans,res);
}
printf("%d\n",ans);
所以最后的代码就是
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=3510;
int b[maxn];
int main(void){
int T;
cin>>T;
while(T--){
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
if(k>=m-1){
int ans=0;
for(int i=1;i<=m;i++){
ans=max(ans,b[i]);
}
for(int i=n;i>=n-m+1;i--){
ans=max(ans,b[i]);
}
printf("%d\n",ans);
}
else{
int ans=0;
for(int l=1;l<=k+1;l++){
int r=n-(k-l+1);
int res=0x3f3f3f3f;
for(int nl=l;nl<=r-(n-m);nl++){
int nr=nl+n-m;
res=min(res,max(b[nl],b[nr]));
}
ans=max(ans,res);
}
printf("%d\n",ans);
}
}
return 0;
}