poj 3273 Monthly Expense

//题意:给你天数n,和每天需要花的钱,让你把这些天分成m份(每份都是连续的天),
//要求每份的和尽量少,输出这个和。

//一开始二分的上界为n天花费的总和(相当于分成1份),下界为每天花费的最大值(相当于分成n份),
//然后二分,每次的mid值为(上界 + 下界)/ 2,然后根据mid值遍历n天花费,对花费进行累加,
//每当超过mid值 份数++,看看这个mid值能把n天分成几份,如果份数大于m,表示mid偏小,下界 = mid + 1,
//反之小于等于mid,上界 = mid,然后输出最后的mid值即可,复杂度为 O(nlogM)

#include <iostream>
#include <algorithm>
#include<numeric>
using namespace std;
int list[100010];
int main()
{
int n,m,i;
cin>>n>>m;
for(i=0;i<n;++i)
{
cin>>list[i];
}
int Max=*max_element(list,list+n),sum=accumulate(list,list+n,0);
int low=Max,high=sum,mid,s,t;
while(low<high)
{
mid=(low+high)/2;
s=0;t=0;
for(i=0;i<n;++i)
{
s+=list[i];
if(s>mid)
{
t++;
if(t>m)
break;
s=list[i];
}
}
if(s>0) //加上最后一份
t++;
if(t<=m) //比较当前分割得到的t份与规定的m份
high=mid;
else
low=mid+1;
}
cout<<low<<endl;
return 0;
}

//对应于 0011序列中最左侧的1的查找(最小值):
//http://duanple.blog.163.com/blog/static/709717672009049528185/

posted on 2011-07-22 15:13  sysu_mjc  阅读(222)  评论(0编辑  收藏  举报

导航