二分+贪心
二分是在一个合理区间内找到合理的答案, 对于这个题则是在合理区间内找到最大的上限。
但是我们得考虑以下得到个例:
9 6
10 10 10 10 10 10 10 10 10
AC:
10 / 10 / 10 / 10 / 10 / 10 10 / 10 10
WA:
10 / 10 / 10 / 10 / 10 10 / 10 10 / 10
考虑清楚上面这个情况。我的代码就AC了
代码如下:
#include <cstdio>
#include <cstring>
int n, k, book[510], f[510];
long long L, R;
int is_ok(long long m)
{
int ans = 0;
long long s = 0;
for(int i = 0;i < n; i++)
{
if(s+book[i]<=m) s+=book[i];
else { ans++; s = book[i];}
if(ans>k-1) return 0;
}
return 1;
}
int main ()
{
int cas, tt;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&k);
R = 0; L = 0;
for(int i = 0; i < n; i++)
{
scanf("%d",&book[i]);
R+=book[i];
if(L<book[i]) L = book[i];
}
long long m;
while(L<R)
{
m = (L+R)/2;
if(is_ok(m)) R = m;
else L = m+1;
}
R = 0; tt = 0;
memset(f,0,sizeof(f));
for(int i = n-1; i >= 0; i--)
{
if(R+book[i]<=L) R+=book[i];
else {R = book[i]; tt++; f[i] = 1;}
}
for(int i = 0; tt<k-1&&i<n; i++) if(!f[i]) {f[i] = 1; tt++;}
for(int i = 0; i < n; i++)
{
if(i) printf(" ");
printf("%d",book[i]);
if(f[i]) printf(" /");
}
printf("\n");
}
return 0;
}