二分 poj 3273

Posted 6262369sss

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分 poj 3273相关的知识,希望对你有一定的参考价值。

题目链接: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的主要内容,如果未能解决你的问题,请参考以下文章

POJ3273 Monthly Expense —— 二分

POJ3273-Monthly Expense-二分答案

POJ 3273 :Monthly Expense二分

Monthly Expense POJ - 3273 (最大值最小化)(二分答案)

POJ 3273 Monthly Expense (二分&最大化最小值)

POJ - 3273Monthly Expense (二分)