一道lightoj 上的题目,我是在上次的一次练习赛中做到的,那时候两个半小时之后就只剩下两题了,而且两题原理是一样的,超开心,结果看了半个小时后这题,一句话:没思路。然后打酱油了。。。囧。
好吧,昨天学二分的时候突然思路来了,果断把那时候还有一题(LightOJ 1076 Get the Containers)给戳掉了。然后么,在这题的打印上又卡了好长时间,,,我好弱啊。。。囧。
好吧,思路就是二分:
//Danceonly
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int INF = 100000007;
#define MIN(a,b) (a > b ? b : a)
#define MAX(a,b) (a > b ? a : b)
int aa[10005];
int N,M;
bool Find(int x)
{
int t = x;
int cnt = 1;
for (int i=0;i<N;i++)
{
if (x < aa[i])return 0;
if (t - aa[i] >= 0)t -= aa[i];
else {t = x - aa[i];if (++cnt > M)return 0;}
}
if (cnt <= M)return 1;
else return 0;
}
void Print(int x)
{
int cnt = 0;
for (int i=0;i<N;i++)
{
if (aa[i]+aa[i+1] > x || N - i == M - cnt){printf("%d\n",aa[i]);cnt++;}
else aa[i+1] += aa[i];
}
}
int main()
{
int T;
scanf("%d",&T);
for (int c=1;c<=T;c++)
{
int sum = 0;
int max_n = 0;
scanf("%d%d",&N,&M);
N++; M++;
for (int i=0;i<N;i++)
{
scanf("%d",&aa[i]);
if (max_n < aa[i])max_n = aa[i];
sum += aa[i];
}
if (N == M)
{
printf("Case %d: %d\n",c,max_n);
for (int i=0;i<N;i++)printf("%d\n",aa[i]);
continue;
}
int r = max_n;
int l = sum;
int mid;
while (l - r >= 1)
{
mid = (l+r)/2;
if (Find(mid))
l = mid;
else
r = mid + 1;
}
while (Find(mid) == 0)mid ++;
printf("Case %d: %d\n",c,mid);
Print(mid);
}
return 0;
}