题目:http://poj.org/problem?id=3273
AC代码(C++):
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <map>
#include <math.h>
#include <string>
#include <string.h>
#include <bitset>
#define INF 0xfffffff
#define MAXN 100105
using namespace std;
int n,m;
int low,high,mid;
int a[100005];
bool isBigger(){
int cnt = 0;
int tmp = 0;
for(int i = 0; i < n; i++){
if(tmp+a[i]<=mid){
tmp+=a[i];
}
else{
tmp = a[i];
cnt++;
}
}
cnt++;
if(cnt>m)return true;
else return false;
}
int main(){
cin>>n>>m;
low = 0;
high = 0;
for(int i = 0; i < n; i++){
cin>>a[i];
high += a[i];
if(a[i]>low)low = a[i];
}
mid = (low+high)/2;
while(low<high){
if(isBigger())low = mid + 1;
else high = mid - 1;
mid = (low+high)/2;
}
cout<<mid;
}
总结: 二分法. 先设low=数组中最大的数, high=数组中所有数的和, 则答案就在low和high之间. 每次循环, 先求出mid, 再把mid当做所求求出分得的组数, 与m做比较. 若比m大则说明分组分多了, 即mid作为答案太小了, 于是把low提高到mid+1, 排除了一半情况.