链接:POJ - 3273
题意:将 N 个数划分给 M 个集合,每个集合包含一个或多个连续出现的数,求划分的集合的最大和的最小是多少,即使划分的集合的最大上限最小。
思路:这个最小值肯定在 最大数 和 n 个数总和之间,所以根据这个进行二分就好。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
#define maxn 100003
int mon[maxn];
int n,m,mmax,sum;
int main()
{
sum = 0;
mmax = 0;
scanf("%d%d",&n,&m);
for(int i = 0;i < n;++i)
{
scanf("%d",&mon[i]);
sum += mon[i];
if(mmax < mon[i]) mmax = mon[i];
}
int r = sum,l = mmax,ans,aans;
while(l <= r)
{
ans = (l+r)/2;
int count = 0,k = 0;
bool flag = 1;
while(k < n)
{
int ss = mon[k];
while(k + 1 < n && ss + mon[k+1] <= ans)
{
k++;
ss += mon[k];
}
k++;
count++;
if(count > m)
{
flag = 0;
break;
}
}
if(flag)
{
r = ans-1;
aans = ans;
}
else l = ans+1;
}
cout<<aans<<endl;
return 0;
}