uva714 - Copying Books
二分+贪心
二分是在一个合理区间内找到合理的答案, 对于这个题则是在合理区间内找到最大的上限。
但是我们得考虑以下得到个例:
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; }