uva714 Copying Books

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1<<29;

int n,k;
ll a[maxn];
int ans[maxn],tmp[maxn];
ll Max,sum;

bool check(ll m)
{
    ll s=0;
    MS0(tmp);
    int cnt=1;
    for(int i=n;i>=1;i--){
        s+=a[i];
        if(s>m){
            s=a[i];
            tmp[i]=1;
            cnt++;
        }
    }
    if(cnt<=k){
        int cur=1;
        while(cnt<k){
            if(!tmp[cur]) tmp[cur]=1,cnt++;
            cur++;
        }
        return 1;
    }
    return 0;
}

void bin(ll l,ll r)
{
    ll res=r;
    MS0(tmp);
    while(l<r){
        ll m=(l+r)>>1;
        if(check(m)) memcpy(ans,tmp,sizeof(tmp)),r=m;
        else l=m+1;
    }
}

int main()
{
    freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%d%d",&n,&k);
        sum=0;Max=-INF;
        REP(i,1,n) scanf("%d",&a[i]),Max=max(a[i],Max),sum+=a[i];
        MS0(ans);
        bin(Max,sum);
        REP(i,1,n){
            printf("%d",a[i]);
            if(ans[i]) printf(" / ");
            else printf("%s",i==n?"
":" ");
        }
    }
    return 0;
}
/**
直接二分检查就可以了,注意答案的优先顺序。
*/
View Code
没有AC不了的题,只有不努力的ACMER!
原文地址:https://www.cnblogs.com/--560/p/5041315.html