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

UVa 714 - Copying Books

2012-08-02 11:04 274 查看
“最大值最小化”问题,先二分求最大值,再贪心实现按最左边区间最小的格式输出 。

代码如下:



#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>

using namespace std;

int main()
{
#ifdef test
freopen("in.txt", "r", stdin);
#endif
int a[505], b[505];
int k, m, num;
scanf("%d", &num);
while(num--)
{
long long left = 0, right = 0, ct, to, mid;
memset(b, 0, sizeof(b));
scanf("%d%d", &m, &k);
for(int i = 0; i < m; i++)
{
scanf("%d", &a[i]);
right += a[i];
}
while(left < right)    // 二分求最大值
{
ct = 0, to = 0;
mid = (left + right) / 2;
for(int i = 0; i < m; i++)
{
to += a[i];
if(a[i] > mid)  // 当单个元素大于中值时,需增大mid的值
{
ct = k;     // 使其跳出
break;
}
if(to >= mid)
{
if(ct >= k)
break;
ct++;
to = a[i];
}
}
if(ct > k - 1)
left = mid + 1;
else
right = mid;
}
for(int cct = 0, tot =0, i = m - 1; i >= 0; i--)  // 贪心
{
tot += a[i];
if(a[i] > mid)    //二分求最大值时可能有一点小误差,当单个元素略大于最大值时,用此更新最大值
mid = a[i];
if(cct < k - 1 && (tot > mid || i < (k - 1) - cct)) // 区间值大于最大值或是所剩元素与所剩区间数相等时都需划分
{
b[i] = 1;
tot = a[i];
++cct;
}

}
for(int i = 0; i < m; i++)
{
printf("%d%c", a[i], i != m-1 ? ' ' : '\n');
if(b[i])
printf("/ ");

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