POJ 3273 二分

/*

题意: 给你天数N(1 ≤ N ≤ 100,000),和每天需要花的钱(存放在数组中),
      让你把这些天分成M(1 ≤ M ≤ N)份(每份都是连续的天),
      要求每份的和最大值尽量小,输出这个和。
分析:二分,用最大money[]为左端点,money[]总和为右端点...要求的结果一定
在该范围内.. 所以要求mid的最优值 
时间复杂度为:n*lg(n)... 

*/
#include<iostream>
#include<algorithm>
#define manx 100009
using namespace std;
int n,m;  /// 天数,人数 
int money[manx];  /// 
bool judge(int mid){ /// 判断 mid 值是否符合条件 
    int sum=0,ans=1;
    for(int i=1;i<=n;i++){
        if(sum+money[i]<=mid)
            sum+=money[i];
        else { sum=money[i]; ans++; }
    }
 //   cout<<ans<<endl;
    if(ans>m) return false;
    else return true;
}
int main(){
    while(cin>>n>>m){
        int right=0,left=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&money[i]);
            if(money[i]>left)
                left=money[i];
            right += money[i];
        }
        int mid=(left+right)>>1; 
        while(left<right){ 
    //        cout<<left<<" "<<mid<<" "<<right<<" ";
            if(!judge(mid))  
                left=mid+1;  /// mid 偏小 
            else
                right=mid-1;  /// mid 偏大 
            mid=(left+right)>>1; 
     //       system("pause");
        }
        cout<<mid<<endl;
    }
}
/*

7 4
100
400
300
100
500
101
400

*/


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值