#include<stdio.h>
int a[100005];
int main(void)
{
int n,m,r,l;
int sum;
int teams;
int max,min;
int i,j;
int mid;
scanf("%d%d",&n,&m); //输入n个物品和m个人
for(i = 1;i <= n;i ++){ //输入n个物品各自的重量,依次序赋值,并保存总重量sum备用
scanf("%d",&a[i]);
sum += a[i];
}
r = sum; //将总数默认为最大生气值的默认值(实际是不是可能的)
l = 0; //将0作为最小生气的人的生气值(从这里的开始计算)
//找到的最大值的控制开关
while(r-l > 1){ //如果最大值和最小时之间相差小于1,则认为已找到最优解
mid=(l + r)/2; //算出中间值(缩小范围,中间的情况也是如此,没必要重复)
sum = 0; //用以记录各个值间的大小大概关系
teams = 1;
for(i = 1;i <= n;i ++){
if(sum + a[i] <= mid)sum += a[i];//最开始时,各值不够大,让他们相加好了
else{ //相加到一定程度后,转换另外一种算法,把他的值降小,重新计算
sum = a[i];
if(sum > mid){ //如果这个值远远大于中间值,则基本上他就是最大值了,
//但亦不排除后面会有值比此大,因此未用break语句</a>; 而是赋予开关一个很大的值
teams = 10000000;
}
teams ++; //开关加1,证明大于平均值的生气值又多了一个
}
}
if(teams > m)l = mid;//生气值大于中间值的人数已大于总人数,也就是说大家可以再上一台阶
else if(teams <= m)r = mid; //否则,大家应当降一个级别,将中间值赋予最大值
}
printf("%d\n",r);
return 0;
}
这种题型有几个特点: 1.连续 2.平均中求最小,最大