二分算法的应用——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;
}

 

posted @ 2017-12-20 22:38  douzujun  阅读(331)  评论(0编辑  收藏  举报