1. 工资
(money/money.in/money.out)
时限1000ms 内存256MB
聪哥在暑假参加了打零工的活动,这个活动分为n个工作日,每个工作日的工资为Vi。有m个结算工钱的时间,聪哥可以自由安排这些时间,也就是说什么时候拿钱,老板说的不算,聪哥才有发言权!(因为聪哥是土豪,他是老板的老板)
聪哥不喜欢身上一次性有太多的钱,于是他想安排一下拿钱的时间,使他一次性拿的钱中最大的最小。(最后一天一定要领钱)
输入
第一行 2个数 n,m
接下来n行,每行一个数,代表Vi.
输出
最小的最大钱数。
样例输入
7 5
100
400
300
100
500
101
400
样例输出
500
样例说明
100 400//300 100//500//101//400//
“//”表示老大要去拿钱。
#include<cstdio>
int n,m,l,r,ans;
int a[100010];
int s[100010];
inline int max(int a,int b)
{return a>b?a:b;}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline bool jud(int k)
{
int sum,piece=m-1,now=1;
while (piece&&now<=n)
{
sum=0;
while (now<=n&&sum+a[now]<=k) sum+=a[now++];
piece--;
}
if (now<=n&&s[n]-s[now-1]>k) return 0;
return 1;
}
int main()
{
freopen("money.in","r",stdin);
freopen("money.out","w",stdout);
n=read();m=read();
for (int i=1;i<=n;i++)
{
a[i]=read();
s[i]=s[i-1]+a[i];
l=max(l,a[i]);
}
r=10000000;
while (l<=r)
{
int mid=(l+r)>>1;
if (jud(mid)){ans=mid;r=mid-1;}
else l=mid+1;
}
printf("%d\n",ans);
}
同bzoj1639……二分
我的r才开10w,结果只有70……