描述
一只木桶能盛多少水,并不取决于桶壁上最高的那块木板,而恰恰取决于桶壁上最短的那块。
已知一个木桶的桶壁由N块木板组成,第i块木板的长度为Ai。
现在小Hi有一个快捷修补工具,每次可以使用修补工具将连续的不超过L块木板提高至任意高度。
已知修补工具一共可以使用M次(M*L<N),如何修补才能使最短的那块木板最高呢?
注意: 木板是环形排列的,第N-1块、第N块和第1块也被视为连续的。
输入
第1行:3个正整数,N, M, L。分别表示木板数量,修补工具使用次数,修补工具每次可以同时修补的木板数。 1≤N≤1,000,1≤L≤20,M*L<N
第2行:N个正整数,依次表示每一块木板的高度Ai,1≤Ai≤100,000,000
输出
第1行:1个整数。表示使用修补工具后,最短木块的所能达到的最高高度
样例说明
第一个修补工具覆盖[2 3 4]
第二个修补工具覆盖[5 8 1]
样例输入
8 2 3 8 1 9 2 3 4 7 5
样例输出
7
#include<iostream>
#include<vector>
using namespace std;
int n, m, l;
int A[1005];
bool check(int k)
{
for(int i = 0; i < n; i++)
{
int r = m;
bool flag = true;
for(int j = 0; j < n && flag; )
{
int t = (i+j) % n;
if(A[t] < k)
{
j += l;
if(--r < 0)
flag = false;
}
else
{
j++;
}
}
if(flag)
return true;
}
return false;
}
int main()
{
cin>>n>>m>>l;
for(int i = 0; i < n; i++)
cin>>A[i];
int left = 1, right = 100000000, k, ans = 0;
do
{
k = (left + right) >> 1;
if(check(k))
{
ans = k;
left = k + 1;
}
else
right = k - 1;
}while(left <= right);
cout<<ans<<endl;
return 0;
}