首页 > 代码库 > poj3273 - Monthly Expense

poj3273 - Monthly Expense

这是一个二分穷举问题,通过二分寻找最小值,不断枚举,但一定要二分结束,否则只要找到m组就结束,不一定是最优解。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=100000+10;
int a[maxn];
int m,n;
bool judge(int mid)
{   int g=1,sum=0;
    for(int i=1;i<=n;i++)
    {    if(sum+a[i]<=mid)
              sum+=a[i];
         else {sum=a[i],g++;}//一组总和大于mid,重新分组,组数加一
    }
    if(g<=m) return true;
    else return false;
}
int main()
{
    int r=0,l=0;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {    scanf("%d",&a[i]);
         if(l<a[i]) l=a[i];//记录max,最为二分最左边的值,因为分组后的最小值必定大于单个的最大值
        r+=a[i];//取总和作为最右边的值
    }
    int mid;
    while(l<r)
    {   mid=(l+r)/2;//此处的mid就是一组的最大值
        if(judge(mid))
        r=mid-1;//能找到<=m组,去取更小的右边界,看能不能找到更小的mid
        else
            l=mid+1;//超过m组,扩大左边界,找够m组
       
    }
    printf("%d\n",mid);

    return 0;
}

 

poj3273 - Monthly Expense