二分算法的应用——Codevs 1766 装果子
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 250000 + 20;
typedef long long LL;
LL a[maxn], v, n, m, max_R, max_L; //max_R是上界, max_l是下界
bool C(LL v) //当前袋子体积 v
{
LL cnt = 1, now = 0;
for(int i = 1;i <= n;i ++)
{
if(now + a[i] <= v) //当前未装满的袋子,尝试是否装下这个树下的苹果,
{ //当前袋子已经装的体积+当前树下苹果体积<=v,就装苹果
now += a[i];
}
else //否则, 用新袋子
{
if(a[i] > v) { //当前树下苹果大于袋子v,就所有袋子都不能装了,直接当前的v,不成立了
return false;
}
cnt ++; //袋子数++
now = a[i]; //用了新袋子, 然后新袋子装了当前树的所有苹果的v
if(cnt > m) { //如果 袋子数 > m
return false;
}
}
}
return true;
}
void solve()
{
cin >> n >> m;
for(int i = 1;i <= n;i ++)
{
cin >> a[i];
max_R += a[i];
max_L = max(max_L, a[i]);
}
LL l = max_L - 1, r = max_R + 1;
while(r - l > 1)
{
LL mid = (l + r) / 2;
if(C(mid)) { //满足,就缩小上界(v)
r = mid;
}
else { //不满足,就提高下界(v)
l = mid;
}
}
cout << r << endl;
}
int main()
{
solve();
return 0;
}