[P1281]书的复制[二分]

来源:互联网 发布:win10系统适合编程吗 编辑:程序博客网 时间:2024/06/06 18:09

原题链接

这个做法是用二分
解最大的页数
然后往这些人手里塞就行了

然后
少了个特判
懒得改了
口头说一句吧
就是判定一下
r是不是解

#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>#include<queue>#include<vector>#include<climits>#include<string>#include<cstdlib>#include<map>#include<ctime>#define MAX 1000000007#define LL long longusing namespace std;struct nico{    int st,en,f;}as[505];int f[505],m,k,bok[505],l,r,mid,ans;int check(int x){    int s=m,p=0,i=0;    memset(f,0,sizeof(f));    while(1)    {        i++;        while(f[i]+bok[s]<=x)        {            f[i]+=bok[s];            if(s==1)            {                p=1;                break;            }            s--;        }        if(p) break;        }    return i;}int main(){    int i,s;    scanf("%d%d",&m,&k);    if(k==0) return 0;    for(i=1;i<=m;i++)    {        scanf("%d",&bok[i]);        r+=bok[i];        l=max(l,bok[i]);        }    while(l<=r)    {        mid=(l+r)/2;        if(check(mid)<=k) r=mid-1;        else l=mid+1;    }    ans=l;    s=m;    for(i=k;i>=1;i--)       {        while(as[i].f+bok[s]<=ans)        {            if(!as[i].f) as[i].en=s;            as[i].st=s;            as[i].f+=bok[s];            if(s==1) break;            s--;                    }           }           for(i=1;i<=k;i++)        printf("%d %d\n",as[i].st,as[i].en);    return 0;}