Uva 714 Copying Books

来源:互联网 发布:义乌淘宝培训班要求 编辑:程序博客网 时间:2024/06/09 17:34
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=655
题目:附件
题意:经典的最大值最小化问题。一些书和一些抄写员,分配任务使总的工作时间最短,即所有抄写员的时间的最大值最小。
题解:小白上有详细解释。    

此题要注意的是
  1. 要求最后多解情况,尽量使得前面的员工工作量尽可能小,所以最后分割从后往前分。
  2. 用long long存储
  3. 考虑最后分组剩余,即斜杠没有都用完,则尽可能在前面插入 。
代码:
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAX=500+10;typedef long long LL;LL a[MAX];int vis[MAX];int N,m,k;bool judge(int x){    LL subsum=0;    int cou=1;    for(int i=m-1; i>=0; i--)    {        subsum+=a[i];        if(subsum>x)        {            subsum=0;            i++;            cou++;        }        if(cou>k)            return false;    }    return cou<=k;}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    cin>>N;    while(N--)    {        cin>>m>>k;        LL right=0;        LL left=0;        for(int i=0; i<m; i++)        {//            scanf("%lld",&a[i]);            cin>>a[i];            right+=a[i];            left=max(left,a[i]);        }        while(left<right)        {            LL mid=(left+right)/2;            if(judge(mid))                right=mid;            else                left=mid+1;        }        LL x0=right;//        cout<<x0<<endl;        memset(vis,0,sizeof(vis));        LL subsum=0;        for(int i=m-1; i>=0; i--)        {            subsum+=a[i];            if(subsum>x0)            {                subsum=0;                vis[i]=1;                i++;                k--;            }        }        while(k-1>0)        {            for(int i=0; i<=m; i++)                if(!vis[i])                {                    vis[i]=1;                    k--;                    break;                }        }        for(int i=0; i<m; i++)        {            if(i) printf(" ");            //printf("%lld",a[i]);            cout<<a[i];            if(vis[i]) printf(" /");        }        printf("\n");    }    return 0;}


原创粉丝点击