POJ 3273
题目描述:
¢ 给定一个数列,要求把数列切分成m个段,使得总和最大的一段的总和最小。求这个总和。
算法分析:
二分查找经典例子,总体思路就是我们先假设mid就是我们要找到答案,看它符不符合题目所给要求(分列成m段,最小),
具体细节看代码。
代码实现:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,m,a[100005],maxx=-1,sum=0,i,j;
cin>>n>>m;
for(i=1;i<=n;i++)
{
cin>>a[i];
sum+=a[i]; //记录右边界
if(maxx<a[i])
maxx=a[i];//记录又边界
}
int l=maxx,r=sum,mid;
int cnt;
while(l<=r)
{
sum=0; //记录划分段的累加和
cnt=0; //记录划分的段数
mid=(l+r)/2;
for(i=1;i<=n;i++)
{
sum+=a[i];
if(sum>mid)
{
cnt++;
sum=0; //不要忘记清0
i--; //不要加这个数,保证sum不大于mid
continue;
}
}
cnt++;//加上最后一段,因为最后一段不在上循环记录
if(cnt>m) //说明分多了,mid偏小
l=mid+1;
else
r=mid-1;
}
cout<<l;
return 0;
}