二分查找(1)
//sicily 2015. A New Year Gift
#include<iostream> //二分答案后贪心验证可行性
using namespace std;
int n,m,arr[1000];
bool verify(int c) //对组数c进行二分
{
int p=0;
for(int i=0;i<n;++i)
p+=min(arr[i],c); //如果arr[i]<c,自然是加上arr[i];若arr[i]>=c,因为一共就c组,所以只能取c
if(p>=m*c) //c组,每组 m 条项链,返回1说明可以分成 c组
return 1;
return 0;
}
int main()
{
while(cin>>n&&n)
{
int sum=0;
for(int i=0;i<n;++i)
{
cin>>arr[i];
sum+=arr[i];
}
cin>>m;
int s=0,t=sum/m,mid; //组数的上下界s,t
while(s<t-1)
{
mid=(s+t)/2;
if(verify(mid))
s=mid; //因为s=mid,所以如果表述成while(s<t),则当s=t-1时,mid=s;若verify(mid)返回真,则s,t的值一直不改变,故循环条件改为 s < t-1
else
t=mid-1;
}
if(verify(t))
cout<<t<<endl;
else
cout<<s<<endl;
}
return 0;
}