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;
}


你可能感兴趣的:(uva714 - Copying Books)