您的位置:首页 > 运维架构

UVa 714 - Copying Books

2012-07-29 13:44 337 查看
最大值最小化问题,二分+贪心,参考刘汝佳白皮书151页。

之前我的代码在UVa上交过了,但是在ZOJ上却是WA。

后来才发现是错在这两组数据:

2

4 3

100000 1 1 1

4 3

1 1 1 100000

#include <cstdio>
#include <cstring>

const int MAXN = 1000 + 10;

int m,k;
long long int num[MAXN];
long long int sum;
bool w[MAXN];

bool Judge( long long int x )
{
int count = 0;
long long int temp = 0;
long long int temp2 = 0;
for ( int i = 0; i < m; )
{
temp += num[i];
if ( temp <= x ) i++;
else
{
temp2 = temp;
temp = 0;
count++;
if ( count > k ) return false;
}
}

if ( temp2 != 0 ) count++;

if ( count > k ) return false;
else return true;
}

long long int Bsearch( long long int x, long long int y )
{
long long int m;

while ( x < y )
{
m = x + (y - x) / 2;
if ( Judge(m) ) y = m;
else x = m + 1;
}
return y;
}

void MaxSum( long long int x )
{
long long int temp = 0;

if ( m == k )
{
printf("%lld", num[0]);
for ( int i = 1; i < m; i++ )
printf(" / %lld", num[i]);
putchar('\n');
return;
}

if ( k == 1 )
{
printf("%lld", num[0]);
for ( int i = 1; i < m; i++ )
printf(" %lld", num[i]);
putchar('\n');
return;
}

int i = 0, j = 0;
memset( w, false, sizeof(w) );

for ( i = m - 1; i >= 0; )
{
temp += num[i];
if ( temp <= x )
i--;
else
{
j++;
w[i] = true;
if ( k - j > i ) break;
temp = 0;
}
}

if ( j < k - 1 )
{
for ( int i = 0; i < m && j < k - 1; i++ )
if ( !w[i] )
{
w[i] = true;
j++;
}
}

printf("%lld", num[0]);
if ( w[0] )  printf(" /");
for ( i = 1; i < m; i++ )
{
printf(" %lld", num[i]);
if ( w[i] && i != m - 1 )  printf(" /");
}

putchar('\n');

return;
}

int main()
{
int T;
scanf( "%d", &T );
while ( T-- )
{
scanf("%d%d", &m, &k);
sum = 0;
for ( int i = 0; i < m; i++ )
{
scanf("%lld", &num[i]);
sum += num[i];
}

MaxSum( Bsearch( 0, sum ) );
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: