- 问题描述
-
The Farmer get a string of consecutive pearls, it contants N pearls. each pearls worth Wi. Unfortunately, the Landlord discover these pearls, the Landlord require the Farmer divide the string of pearls into M short consecutive pearls, and the Landlord will get The most expensive short consecutive pearls.
The Farmer want to give the Landlord short consecutive pearls as cheap as possible.
- 输入
-
This problem has several cases.
for each case, first line have two integer N(1 <= N <= 10^6) and M (1 <= M <= N)
the second line have N integer, it means the Wi(i = 1 ... N, 1 <= Wi <= 100).
- 输出
-
For each case, print the least wealth of the short consecutive pearls Landlord will get.
- 样例输入
6 3 1 2 3 2 5 4
- 样例输出
7
- 提示
无
- 来源
Monkeyde17
- 本题是最大值最小化问题
- 思路如下,换成另一个问题,是否可以把所有的数划分成m份,使得每一份的和加起来都不超过x,那么最小的x就是答案了
- 接下来就是二分的做法,先猜个数,判断可以不可以,如果可以,那么答案一定是小于等于那个数,否则答案一定大于那个数
#include<stdio.h>
#define maxn 1000010
int pearls[maxn];
int n,m;
bool judge(int x)
{
__int64 sum=0;
int i,seg=0;
for(i=1;i<=n;i++)
{
sum+=pearls[i];
if(pearls[i]>x)//这一步千万不要忘,因为如果存在单独的元素,他已经比x大了,那么绝对不满足
return false;
if(sum>x)//如果sum+当前的元素超过x,为了满足每个字段的和都小于x,得多开一个段
{
sum=pearls[i];
seg++;
}
}
return !(seg>=m);//如果划分的段数超过m,那么说明,把超过的段数分到m组里,一定会使其中几组的和超过x,那么就不满足了,否则就有可能。
}
__int64 huafen(int low,int high)
{
while(low<=high)
{
int mid=(low+high)/2;
if(judge(mid))
high=mid-1;
else
low=mid+1;
}
return high+1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int i,min=1000;
__int64 max=0;
for(i=1;i<=n;i++)
{
scanf("%d",&pearls[i]);
if(pearls[i]<min)
min=pearls[i];
max+=pearls[i];
}
__int64 ans=huafen(min,max);
printf("%I64d\n",ans );
}
return 0;
}