poj3273

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

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

View Code
#include < cstdio >
#include
< iostream >
#include
< cstdlib >
#include
< cstring >
using namespace 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)
return false ;
return true ;
}

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();
return 0 ;
}

你可能感兴趣的:(poj)