poj3273

题意:给定一个数列,要求把数列切分成m个段,使得总和最大的一段的总和最小。求这个总和。

分析:只知道dp的方法,但是超时。后来知道是二分。就是二分查找一个阶段消费的上限(总和)。每次可以用O(n)的效率来判断这个值是不是符合。我们要找的就是符合条件的最小值。

View Code
#include <cstdio>
#include
<iostream>
#include
<cstdlib>
#include
<cstring>
usingnamespace std;

#define maxn 100005

int n, m, f[maxn], l, r, mid;

void init()
{
scanf(
"%d%d", &n, &m);
l
=0;
r
=0;
for (int i =0; i < n; i++)
{
scanf(
"%d", &f[i]);
if (l < f[i])
l
= f[i];
r
+= f[i];
}
}

bool ok(int a)
{
int sum =0, j =0;

for (int i =0; i < n; i++)
{
if (sum + f[i] > a)
{
sum
= f[i];
j
++;
}
else
sum
+= f[i];
}
j
++;
if (j > m)
returnfalse;
returntrue;
}

void binarysearch()
{
while (l < r)
{
mid
= (l + r) /2;
if (!ok(mid))
l
= mid +1;
else
r
= mid;
}
printf(
"%d\n", l);
}

int main()
{
//freopen("D:\\t.txt", "r", stdin);
init();
binarysearch();
return0;
}
posted @ 2011-02-22 16:31  金海峰  阅读(1129)  评论(2编辑  收藏  举报