Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 15822 | Accepted: 6321 |
Description
Farmer John is an astounding accounting wizard and has realized he might run out of money to run the farm. He has already calculated and recorded the exact amount of money (1 ≤ moneyi ≤ 10,000) that he will need to spend each day over the next N (1 ≤ N ≤ 100,000) days.
FJ wants to create a budget for a sequential set of exactly M (1 ≤ M ≤ N) fiscal periods called "fajomonths". Each of these fajomonths contains a set of 1 or more consecutive days. Every day is contained in exactly one fajomonth.
FJ's goal is to arrange the fajomonths so as to minimize the expenses of the fajomonth with the highest spending and thus determine his monthly spending limit.
Input
Lines 2..N+1: Line i+1 contains the number of dollars Farmer John spends on the ith day
Output
Sample Input
7 5
100
400
300
100
500
101
400
Sample Output
500
Hint
Source
题目链接:http://poj.org/problem?id=3273
题目大意:给出一个人在n天的花费,要求将其分成m组,每组的天数是连续的,要使得每组花费之和尽可能的小,求各组花费之中的最大值
题目分析:显然那个划分的值是有范围的,我们令范围的上限为所有花费之和,即划分为1组,范围的下限为所有话费中的最大值,即划分为n组,因为要求的是各组花费的最大值,然后答案就在这个范围之间了,我们通过二分枚举每一个在当前范围内的划分,模拟分组过程,因为要求每组是连续的,最后划分出来的组数如果小于m则说明划分值偏大,否则划分值偏小,若相等则继续枚举,注意这里不能退出,因为这只是一组合法解,题目要求的是使得每组花费之和尽可能的小,意思差不多相当于尽可能均分,因此要继续二分枚举直到二分结束。
#include <cstdio>
#include <algorithm>
using namespace std;
int c[100005];
int main()
{
int n, m, sum = 0, ma = 0, l, r, mid;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; i++)
{
scanf("%d", &c[i]);
sum += c[i];
ma = max(ma, c[i]);
}
r = sum;
l = ma;
mid = (l + r) / 2;
while(l < r)
{
int tmp = 1, now = 0;
for(int i = 0; i < n; i++)
{
if(c[i] + now <= mid)
now += c[i];
else
{
now = c[i];
tmp++;
}
}
//这里注意不能反!!因为有等于的情况,因为tmp=m时我们要尽量减小划分值
//这是题目的要求,让各组和尽可能小,反了肯定wa
if(tmp > m)
l = mid + 1;
else
r = mid - 1;
mid = (l + r) / 2;
}
printf("%d\n", mid);
}