Monthly Expense
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 21448 | Accepted: 8429 |
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
Line 1: Two space-separated integers: N and M
Lines 2..N+1: Line i+1 contains the number of dollars Farmer John spends on the ith day
Output
Line 1: The smallest possible monthly limit Farmer John can afford to live with.
Sample Input
7 5 100 400 300 100 500 101 400
Sample Output
500
Hint
If Farmer John schedules the months so that the first two days are a month, the third and fourth are a month, and the last three are their own months, he spends at most $500 in any month. Any other method of scheduling gives a larger minimum monthly limit.
Source
题目大意:给你未来n天FJ每天需要花费的钱的数目,FJ想要将这些天划分成k个时期,问你划分之,
花钱最多的那一段日子钱数最少是多少。(最大值最小化问题)
思路分析:很明显的二分,类似的最小值最大化最大值最小化,而且看一下数据范围,同时一般还会给出一个限制条件
让你写check函数,如本题中k值就是check函数中的判断条件,弱很快敲完,但还是wa了两发,最近一直在做二分的
题目,每道题总会wa几发,教我点做人道理,本题弱wa在在了二分初始区间的确定上,本来我以为二分初始区间尽量
大些,将答案包含进去就没问题了,所以直接不假思索将左边界赋成了0,结果wa了,后面想明白了,初始区间确实可
以大些,但是你一旦把那些根本不可能的答案包含进去,check函数写起来就要麻烦的多,我写的check函数是建立在
x>a[maxn]的情况下的,但是区间却没有这样选择,因此以后为了避免不必要的麻烦,还是将初始区间定的精确一些。
代码:
#include <iostream>
#include<algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
using namespace std;
const int maxn=100000+100;
int a[maxn];
int n,k;
bool check(__int64 x)
{
int t=0;
__int64 sum=0;
for(int i=0;i<n;i++)
{
sum+=a[i];
if(sum>x)
{
sum=a[i];
t++;
}
}
if(t+1>k) return false;
else return true;
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
__int64 sum=0;
int ma=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(ma<a[i])ma=a[i];
sum+=a[i];
}
__int64 l=ma,r=sum;
__int64 ans;
while(l<=r)
{
__int64 mid=(l+r)>>1;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",ans);
}
return 0;
}