首页 > 其他 > 详细

二分 poj 3273

时间:2018-08-08 11:00:13      阅读:146      评论:0      收藏:0      [点我收藏+]

题目链接:https://vjudge.net/problem/POJ-3273

把n个连续的数字划分成m个连续的部分,每个部分都有一个部分和(这个部分所有值加起来),现在要使划分里最大的那个部分和最小。

我用的也是二分,用二分枚举最大的部分和。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<cstdio>
using namespace std;
#define eps 1e-8
#define ll long long
#define INF 0x3f3f3f3f
ll n,m,money[100005];
ll jug(ll mid)    //循环一次判断mid 
{
    ll cnt=0;    //计数 
    ll sum=money[0];
    cnt++;
    if(sum>mid)
    return 0; 
    if(cnt>m)
    return 0;
    for(int i=1;i<n;i++)
    {
        if(sum+money[i]<=mid)
        {
            sum+=money[i];
        }
        else
        {
            sum=money[i];
            if(sum>mid)
            return 0;
            cnt++;
            if(cnt>m)
            return 0;
        }
    }
    return 1;
}
ll two_(ll l,ll r)    //二分求最小 
{
    ll mid,pos;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(jug(mid))    //判断这个mid值是否可行, 
        {
            r=mid-1;
            pos=mid;    //pos记录当前值,这种写法比较保险,因为r值不一定可行,但是mid值是一定可行的 
        }
        else
        {
            l=mid+1;
            pos=l;
        }
    }
    return pos;
}
int main()
{
    while(cin>>n>>m)
    {
        ll sum=0;
        for(int i=0;i<n;i++)
        {
            cin>>money[i];
            sum+=money[i];
        }
        cout<<two_(1,sum)<<endl;
    }
    return 0;
}

 

二分 poj 3273

原文:https://www.cnblogs.com/6262369sss/p/9441428.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!