题目:
输入
N=4
K=11
L = {8.02, 7.43, 4.57, 5.39}
输出
2.00 (每条绳子分別可以得到4条、3条、2条、2条,共计11条绳子)
分析:
这个问题用二分搜索可以非常容易地求得答案。让我们套用二分搜索的模型试着解决这个问题。令:
条件Cmp(x):=计算可以得到K条长度为x的绳子数
则问题变成了求满足C(x)条件的最大的x。在区间初始化时,只需使用充分大的数INF(==1e9)作为上界即可:
lb=0
ub=INF
现在的问题是是否可以高效地判断cmp(x)。由于长度为L,的绳子最多可以切出floor(Li/ x)段长度为x绳子,因此
C(x)=floor(L/x)的总和是否大于或等于K)
它可以在O(N)的时间内被判断出来。
代码实现:
#include<iostream>
#include<vector>
using namespace std;
int n,k;
vector<double> L;
bool cmp(double x) {
int sum=0;
for(int i=0; i<n; ++i)
sum+=(int)(L[i]/x);
return sum>=k;
}
int main() {
cin>>n>>k;
L.resize(n);
for(int i=0; i<n; ++i)
cin>>L[i];
double l=0,r=1e9;
for(int i=0; i<100; ++i) {
double mid=(l+r)/2;
if(cmp(mid))
l=mid;
else r=mid;
}
cout<<l;
return 0;
}